C++ 的异常操作
1.、异常涉及的关键字有哪些?
- throw 抛出异常 。
- try 中包含的是可能出现异常的语句,后面可以跟多个catch。
- catch 用于捕获异常后面括号中跟的是异常的类型,其中包含的是处理方法。
解释一下重抛异常:当catch捕获到一个异常,可以在这个catch中再次throw抛出异常,但这个throw后面可以不跟内容,表示继续抛出原来的异常。(注:我没理解你抛得都是一样的,catch是按异常类型捕获的,这个重抛的意义在哪里?)
在C++中异常是可以不处理的,但在java等其他语言中中异常是一定要处理的。
再来说一下:在try中定义有很多异常,如果有一个异常先出来,后面的释放就不执行了,如何处理:智能指针。
try
{
//int *p1 = new int;
//int *p2 = new int;
//int *p3 = new int; 假设p3抛出了异常,地下的delete就不执行了,直接跳到catch里了。
//int *p4 = new int;
unique_ptr<int> ptr1(new int);
unique_ptr<int> ptr2(new int);
unique_ptr<int> ptr3(new int);
unique_ptr<int> ptr4(new int);
//delete p1;
//delete p2;
//delete p3;
//delete p4;
}
catch (const bad_alloc& e)
{
}
2. 你碰见过哪些异常?
new int();
3. 异常的栈展开是怎么回事?
函数抛出的异常会沿着函数调用链逆向抛出,如果到系统,系统调用terminate()终止整个程序。
举个例子,解释一下:
函数中有个调用链,main -> A -> B -> C 如果C抛出异常,先在C函数栈帧中找处理该异常的程序。如果没找到,回到B中找,找到了再返回C继续执行。如果main都没有,再抛给系统,系统调用terminate()。
4、构造函数和析构函数是否可以抛出异常?
语法上来说都是可以的。但是!!!
构造函数抛出异常,对象没有构造成功,对象都没有,又怎么会调用析构函数。处理方法是:如果在构造函数中要抛出异常,则在抛出前要记得删除申请的资源。或者直接使用智能指针即可。
析构函数也不能抛出异常,处理析构函数异常的正确方式是将异常封装在析构函数内部,而不是抛出异常,如下代码所示。
~ClassName()
{
try
{
do_something();
}
catch
{
//...
}
}
原因如下:C++异常处理模型有责任处理那些因为出现异常而失效的对象,处理方式是调用这些失效对象的析构函数,释放掉它们占用的资源。如果析构函数再抛出异常,则会陷入无尽递归嵌套之中,因此这是不被允许的。