构造函数中抛出的异常:析构函数是否被调用?

时间:2014-06-12 14:06:26

标签: c++

如果在对象的构造函数中抛出异常,那么是否会调用析构函数?还是未定义的行为? (这就是为什么我不愿意说出我的编译器的作用。)

struct foo()
{
    foo(){
        throw "bar";
    }
    ~foo(){
        /*am I called*/
    }
};

foo f;

2 个答案:

答案 0 :(得分:3)

析构函数不会被调用,因为foo对象在构造函数完成执行之前不被认为是完全构造的(请注意,这意味着如果你抛出一个委托给不同构造函数的构造函数,那么析构函数被召唤)。从构造函数中抛出并不是未定义的行为。

答案 1 :(得分:1)

对象的生命周期在其构造函数完成执行时开始。这意味着,在构造函数执行结束之前,该对象从未存在过。因此,没有活动对象,因此,没有析构函数可以调用。

因此,除非创建异常对象引发另一个异常,否则没有未定义的行为。在这种情况下,程序会中止。

但是,在异常之前完全构造的任何其他对象都被适当地破坏,包括基础子对象,其他成员对象,在抛出异常的函数的同一范围内声明的本地对象,以及之前没有的任何其他对象抓住那个例外。

查看,堆栈展开(在stackoverflow,google和wikipedia上,按优先顺序排列)。