error:terminate called after throwing an instance of 'char'

C++析构函数异常
zhuan http://blog.etrnls.net/2008/06/03/cpp_destructor_exception/#more-72

C++标准中说可以假定析构函数不抛出异常,而如果特定情况下析构函数抛出异常将自动调用terminate()终止程序。

我们来看一下这条“站着说话不腰疼“的假定。首先要明确,C++的异常是和面向对象无缝结合的,自然它要保证异常发生时局部变量的正常销毁。当异常抛出的时候,有一个栈展开(stack unwinding)的过程,也就是异常抛出点到最近的catch该异常的地方之间的所有的栈页面被弹出,而页面中的所有的局部对象会被析构,可以看到,析构是和异常处理紧密结合在一起的。

现在假设在异常被激活的情况下(比如某个地方抛出了一个MyException)调用某个析构函数,而这个析构函数又抛出了一个异常(比如叫AnotherException),那么现在应该怎么办?是忽略这个新的exception继续找能够catch MyException的地方呢还是扔掉MyException开始找能够处理AnotherException的地方呢?

因此C++语言担保,当处于这一点时,会调用terminate()来杀死进程。所以,如果在析构函数中抛出异常的话就不要指望谁能catch了。

如果析构函数真的可能会抛异常呢?其实这可能是不可避免的,那么就一定要把这个异常控制在析构函数内部,千万不能让它跑出去,一旦跑出去后果不堪设想,很可能程序就此crash。

而我们写程序的时候就可以像标准中说的一样,默认析构不会产生异常。

最后看一段代码演示一下~

#include <iostream>
#include <exception>
using namespace std;
class Foo
{
public:
Foo()
{
cerr << "Foo ctor" << endl;
}
~Foo()
{
cerr << "Foo dtor" << endl;
throw "Bad exception!";
}
void doSomething()
{
throw "The exception";
}
};
class Bar
{
public:
Bar()
{
cerr << "Bar ctor" << endl;
}
~Bar()
{
cerr << "Bar dtor" << endl;
}
};
void fun1()
{
Foo foo;
foo.doSomething();
}
void fun2()
{
Bar bar;
fun1();
}
void fun3()
{
try
{
fun2();
}
catch (...)
{
cerr << "Caught exception" << endl;
}
}
int main()
{
fun3();
return 0;
}

运行结果(g++ (GCC) 4.1.2 (Gentoo 4.1.2 p1.1)编译):

Bar ctor
Foo ctor
Foo dtor
terminate called after throwing an instance of ‘char const*’
Aborted
恩,Bar的析构函数没有调用而程序直接被terminate掉了。当然如果doSomething的时候没有抛出异常那么这个程序是可以正常结束的,所以有时候会发现原来的代码跑的好好的而新加了一部分代码程序就崩溃了,仔细检查新的代码又没有发现什么问题,其实原来的代码”好好“的运行只是假想而已……

P.S.:稍稍偏题,如果构造函数中抛出异常,是不会调用析构函数的,C++认为该对象还没真正”活“过,所以不需要”死“了,而据说Object Pascal认为既然构造函数抛异常了那这个对象已经”半活“了,所以需要调用析构函数让它”死“一遍。?

  • 4
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值