【发布时间】:2014-08-02 21:39:08
【问题描述】:
如果在对象的构造函数中抛出异常,那么会调用析构函数吗?还是未定义的行为? (这就是为什么我不愿意说我的编译器做了什么。)
struct foo()
{
foo(){
throw "bar";
}
~foo(){
/*am I called*/
}
};
foo f;
【问题讨论】:
标签: c++
如果在对象的构造函数中抛出异常,那么会调用析构函数吗?还是未定义的行为? (这就是为什么我不愿意说我的编译器做了什么。)
struct foo()
{
foo(){
throw "bar";
}
~foo(){
/*am I called*/
}
};
foo f;
【问题讨论】:
标签: c++
不会调用析构函数,因为 foo 对象在构造函数完成执行之前不会被认为是完全构造的(请注意,这意味着如果你抛出一个委托给不同构造函数的构造函数,那么析构函数 将 被称为)。从构造函数中抛出不是未定义的行为。
【讨论】:
auto_ptr 在 C++11 中已弃用。但任何其他 smart pointers 都可以。如果您需要跨 C++ 版本移植,boost::shared_ptr 可以。
~foo 没有被调用,但数据成员的析构函数将被调用,因为数据成员已经完全构造。
对象的生命周期从其构造函数完成执行开始。这意味着,在构造函数执行结束之前,该对象从未存在过。因此,没有活动对象,因此没有可调用的析构函数。
因此,没有未定义的行为,除非创建异常对象引发另一个异常。在这种情况下,程序会立即中止。
但是,在异常被适当销毁之前完全构造的任何其他对象,包括基础子对象、其他成员对象、在抛出异常的函数的同一范围内声明的本地对象,以及之前范围内没有的任何其他对象捕获该异常。
检查一下,stack unwinding(在 stackoverflow、google 和 wikipedia 上,按优先顺序)。
【讨论】: