如果在对象的构造函数中抛出异常,那么是否会调用析构函数?还是未定义的行为? (这就是为什么我不愿意说出我的编译器的作用。)
struct foo()
{
foo(){
throw "bar";
}
~foo(){
/*am I called*/
}
};
foo f;
答案 0 :(得分:3)
析构函数不会被调用,因为foo
对象在构造函数完成执行之前不被认为是完全构造的(请注意,这意味着如果你抛出一个委托给不同构造函数的构造函数,那么析构函数将被召唤)。从构造函数中抛出并不是未定义的行为。
答案 1 :(得分:1)
对象的生命周期在其构造函数完成执行时开始。这意味着,在构造函数执行结束之前,该对象从未存在过。因此,没有活动对象,因此,没有析构函数可以调用。
因此,除非创建异常对象引发另一个异常,否则没有未定义的行为。在这种情况下,程序会中止。
但是,在异常之前完全构造的任何其他对象都被适当地破坏,包括基础子对象,其他成员对象,在抛出异常的函数的同一范围内声明的本地对象,以及之前没有的任何其他对象抓住那个例外。
查看,堆栈展开(在stackoverflow,google和wikipedia上,按优先顺序排列)。