C++中try--catch⽤法
在c++中,可以直接抛出异常之后⾃⼰进⾏捕捉处理,如:(这样就可以在任何⾃⼰得到不想要的结果的时候进⾏中断,⽐如在进⾏数据库事务操作的时候,如果某⼀个语句返回SQL_ERROR则直接抛出异常,在catch块中进⾏事务回滚(回滚怎么理解?))。
#include <iostream>
#include <exception>
using namespace std;
int main () {
try
{
throw 1;
throw "error";
}
catch(char *str)
{
cout << str << endl;
}
catch(int i)
{
cout << i << endl;
}
}
也可以⾃⼰定义异常类来进⾏处理:
#include <iostream>
#include <exception>
using namespace std;
//可以⾃⼰定义Exception
class myexception: public exception
{
virtual const char* what() const throw()
{
return "My exception happened";
}
}myex;
int main () {
try
{
if(true) //如果,则抛出异常;
throw myex;
}
catch (exception& e)
{
cout << e.what() << endl;
}
return 0;
}
同时也可以使⽤标准异常类进⾏处理:
#include <iostream>
#include <exception>
using namespace std;
int main () {
try
{
int* myarray= new int[100000];
}
catch (exception& e)
{
cout << "Standard exception: " << e.what() << endl;
}
return 0;
}
⼀、简单的例⼦
⾸先通过⼀个简单的例⼦来熟悉C++ 的 try/catch/throw(可根据单步调试来熟悉,try catch throw部分是如何运⾏的):
try catch的使用方法#include <stdlib.h>
#include "iostream"
using namespace std;
double fuc(double x, double y) //定义函数
{
if(y==0)
{
throw y; //除数为0,抛出异常
}
return x/y; //否则返回两个数的商
}
int _tmain(int argc, _TCHAR* argv[])
{
double res;
try //定义异常
{
res=fuc(2,3);
cout<<"The result of x/y is : "<<res<<endl;
res=fuc(4,0); //出现异常
}
catch(double) //捕获并处理异常
{
cerr<<"error of dividing zero.\n";
exit(1); //异常退出程序
}
return 0;
}
catch 的数据类型需要与throw出来的数据类型相匹配的。
⼆、catch(...)的作⽤
catch(…)能够捕获多种数据类型的异常对象,所以它提供给程序员⼀种对异常对象更好的控制⼿段,使开发的软件系统有很好的可靠性。因此⼀个⽐较有经验的程序员通常会这样组织编写它的代码模块,如下:
void Func()
{
try
{
// 这⾥的程序代码完成真正复杂的计算⼯作,这些代码在执⾏过程中 // 有可能抛出DataType1、DataType2和DataType3类型的异常对象。
}
catch(DataType1& d1)
{
}
catch(DataType2& d2)
{
}
catch(DataType3& d3)
{
}
/*********************************************************
注意上⾯try block中可能抛出的DataType1、DataType2和DataType3三 种类型的异常对象在前⾯都已经有对应的catch block来处理。但为什么
还要在最后再定义⼀个catch(…) block呢?这就是为了有更好的安全性和 可靠性,避免上⾯的try block抛出了其它未考虑到的异常对象时导致的程 序出现意外崩溃的严重后果,⽽且这在⽤VC开发的系统上更特别有效,因 为catch(…)能捕获系统出现的异常,⽽系统异常往往令程序员头痛了,现 在系统⼀般都⽐较复杂,⽽且由很多⼈共同开发,⼀不⼩⼼就会导致⼀个 指针变量指向了其它⾮法区域,结果意外灾难不幸发⽣了。catch(…)为这种 潜在的隐患提供了⼀种有效的补救措施。
*********************************************************/
catch(…)
{
}
}
三、异常中采⽤⾯向对象的处理
⾸先看下⾯的例⼦:
void OpenFile(string f)
{
try
{
// 打开⽂件的操作,可能抛出FileOpenException
}
catch(FileOpenException& fe)
{
// 处理这个异常,如果这个异常可以很好的得以恢复,那么处理完毕后函数 // 正常返回;否则必须重新抛出这个异常,以供上层的调⽤函数来能再次处 // 理这个异常对象
int result = ReOpenFile(f);
if (result == false) throw;
}
}
void ReadFile(File f)
{
try
{
// 从⽂件中读数据,可能抛出FileReadException
}
catch(FileReadException& fe)
{
// 处理这个异常,如果这个异常可以很好的得以恢复,那么处理完毕后函数 // 正常返回;否则必须重新抛出这个异常,以供上层的调⽤函数来能再次处
// 理这个异常对象
int result = ReReadFile(f);
if (result == false) throw;
}
}
void WriteFile(File f)
{
try
{
// 往⽂件中写数据,可能抛出FileWriteException
}
catch(FileWriteException& fe)
{
// 处理这个异常,如果这个异常可以很好的得以恢复,那么处理完毕后函数
// 正常返回;否则必须重新抛出这个异常,以供上层的调⽤函数来能再次处理这个异常对象 int result = ReWriteFile(f);
if (result == false) throw;
}
}
void Func()
{
try
{
// 对⽂件进⾏操作,可能出现FileWriteException、FileWriteException
// 和FileWriteException异常
OpenFile(…);
ReadFile(…);
WriteFile(…);
}
// 注意:FileException是FileOpenException、FileReadException和FileWriteException // 的基类,因此这⾥定义的catch(FileException& fe)能捕获所有与⽂件操作失败的异
// 常。
catch(FileException& fe)
{
ExceptionInfo* ef = fe.GetExceptionInfo();
cout << “操作⽂件时出现了不可恢复的错误,原因是:”<< fe << endl;
}
}
下⾯是更多⾯向对象和异常处理结合的例⼦:
#include <iostream.h>
class ExceptionClass
{
char* name;
public:
ExceptionClass(const char* name="default name")
{
cout<<"Construct "<<name<<endl;
this->name=name;
}
~ExceptionClass()
{
cout<<"Destruct "<<name<<endl;
}
void mythrow()
{
throw ExceptionClass("my throw");
}
}
void main()
{
ExceptionClass e("Test");
try
{
}
catch(...)
{
cout<<”*********”<<endl;
}
}
这是输出信息:
Construct Test
Construct my throw
Destruct my throw
****************
Destruct my throw (这⾥是异常处理空间中对异常类的拷贝的析构)
Destruct Test
======================================
不过⼀般来说我们可能更习惯于把会产⽣异常的语句和要throw的异常类分成不同的类来写,下⾯的代码可以是我们更愿意书写的:
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论