一.C++异常处理机制的组成部分?
try(检查) ,throw(抛出),catch(捕获)。
将需要检查的语句放在try块中,throw用来当出现异常时抛出一个异常信息,而catch则用来捕获异常信息,如果捕捉到了异常信息,就处理它。
二.try
1.try块可以嵌套
2.程序按顺序寻找匹配的异常处理器,抛出的异常将被第一个类型符合的异常处理器捕获
3.如果内层try块后面没有找到合适的异常处理器,该异常向外传播,到外层try块后面的catch块中寻找
4.没有被捕获的异常将调用terminate函数,terminate函数默认调用abort终止程序的执行,可以使用set_terminate函数指定terminate函数将调用的函数
三.throw
1.可以抛出内置类型异常也可以抛出自定义类型异常
2.throw抛出一个类对象会调用拷贝构造函数,因此常抛出临时对象,
e.g. throw Myexception(“Myexception”);
3.抛出异常后,异常发生之前创建的局部对象被销毁,这一过程称为栈展开
什么是栈展开?
当一个函数里面抛出异常时,如果抛出的异常没有在该函数里面找到相应的catch处理模块,这个时候在抛出异常前的那些局部变量就开始销毁,最后整个函数调用的栈帧也被销毁。异常就到了调用该函数的去找catch处理模块,如果也没有 那么一样要销毁该调用函数的栈帧。就这样一层层的往外推。这样的一个过程就是栈展开了
四.catch
1.一个异常处理器一般只捕捉一种类型的异常
2.异常处理器的参数类型和抛出异常的类型相同
3. …表示可以捕获任何异常
注意:
1.讲派生类放在基类catch的上面,否则的话异常信息都会被基类接走
2.接指针的异常
例:
throw new MyExceptionD(“MyException”);
catch(MyExceptionD *e)
{
cout << e->what() << endl;
delete e;
}
我们一般不抛出指针的异常,防止出现浅拷贝。
catch(void *) 接受任何指针的异常,一般放最后。
示例测试代码附录:
1.demo1.cpp
#include <iostream>
using namespace std;
double div(double a, double b)
{
if(b == 0.0)
{
//throw(1);
throw(5.2);
}
return a / b;
}
void myterminate()
{
cout << "my terminate" << endl;
}
int main()
{
set_terminate(myterminate);
try
{
div(5.0, 0.0);
}
catch(int)
{
cout << "div zero" << endl;
}
catch(double a)
{
cout << "a=" << a << endl;
cout << "double zero" << endl;
}
catch(...)
{
cout << "other zero" << endl;
}
}
2.demo2.cpp
#include <iostream>
#include <string>
using namespace std;
class MyException
{
public:
MyException(char *message) : message_(message)
{
cout << "constructor MyException" << endl;
}
MyException(const MyException& other) : message_(other.message_)
{
cout << "copy constructor MyException" << endl;
}
~MyException()
{
cout << "destroy MyException" << endl;
}
const char * what() const
{
return message_.c_str();
}
private:
string message_;
};
class MyExceptionD : public MyException
{
public:
MyExceptionD(char *message) : MyException(message)
{
cout << "constructor MyExceptionD" << endl;
}
~MyExceptionD()
{
cout << "destroy MyExceptionD" << endl;
}
};
class Test
{
public:
Test()
{
cout << "constructor Test" << endl;
}
~Test()
{
cout << "destroy Test" << endl;
}
};
int main()
{
try
{
// Test t;
// MyException e("MyException!");
throw(e);
throw MyExceptionD("MyException");
throw new MyExceptionD("MyException");
}
catch(void *)
{
cout << "void *" << endl;
}
catch(int)
{
cout << "exception int" << endl;
}
catch(MyExceptionD& e)
{
cout << e.what() << endl;
}
catch(MyException& e)
{
cout << "Base " << e.what() << endl;
}
catch(MyExceptionD *e)
{
cout << e->what() << endl;
delete e;
}
return 0;
}