如果对象在构造函数中引发异常,是否会调用基类的析构函数?如果对象在构造函数中抛出异常,基类的析构函数会调用吗?
回答
如果在施工过程中抛出异常,所有先前构造的子对象都将被正确销毁。下面的程序证明该基地是绝对销毁:
struct Base
{
~Base()
{
std::cout << "destroying base\n";
}
};
struct Derived : Base
{
Derived()
{
std::cout << "throwing in derived constructor\n";
throw "ooops...";
}
};
int main()
{
try
{
Derived x;
}
catch (...)
{
throw;
}
}
输出:
throwing in derived constructor
destroying base
(请注意,本机指针的析构函数什么都不做,这就是为什么我们喜欢RAII通过原始指针。)
是的。规则是构造函数成功完成的每个对象都将在异常时被破坏。例如:
class A {
public:
~A() {}
};
class B : public A {
public:
B() { throw 0; }
~B() {}
};
〜A()被调用。 〜B()不被调用;
编辑:此外,假设有成员:
struct A {
A(bool t) { if(t) throw 0; }
~A() {}
};
struct B {
A x, y, z;
B() : x(false), y(true), z(false) {}
};
会发生什么事是:X构造,Y抛出,x被破坏(但既不Ÿ也不Z)。
当一个异常被抛出,析构函数呼吁所有(子)对象,它们的构造进行了成功运行。这扩展到数据成员和基类。
例如,对于这个代码
struct base {};
struct good {};
struct bad {
bad() {throw "frxgl!";}
};
struct test : public base {
std::string s;
good g;
bad b;
test() {}
};
之前test
的构造被执行时,第一基类的构造函数被调用,那么对于s
,g
,和b
构造函数。只有这些成功完成,才会执行test
的构造函数。在构建b
期间抛出异常时,基类构造函数以及数据成员s
和g
的构造函数已完全执行,因此它们的析构函数已运行。 test
本身和b
的构造函数尚未成功运行,因此它们的析构函数未运行。
从标准文档,15.3 - 11,
的完全构造基类和对象的成员应输入功能的处理程序之前被破坏试戴构造的 块或该对象的析构函数。
很好的引用,但它不回答这个问题。 – fredoverflow 2010-09-21 10:29:49
@FredOverflow,是啊谢谢...现在更新.. :) – liaK 2010-09-21 10:34:38
- 1. 如果派生类析构函数抛出一个异常,基类析构函数会发生什么
- 2. 从构造函数中抛出异常
- 3. ServerSocket的构造函数抛出异常
- 4. EJB3构造函数抛出异常?
- 5. Angular2,构造函数DI抛出异常
- 6. 如果函数返回提前或抛出异常,是否会调用对象的析构函数?
- 7. 如果我从构造函数中抛出异常,构造函数中的释放内存会发生什么?
- 8. 在C++类的构造函数中抛出异常
- 9. new []/delete []并在C++中抛出构造函数/析构函数
- 10. 调用可以在C++中抛出异常的函数的析构函数
- 11. 从JNI函数抛出java异常之后调用C++析构函数吗?
- 12. 结构基类抛出异常对象
- 13. 构造函数中的调用基构造函数和其他构造函数
- 14. 在构造函数结束时抛出异常是否会损坏对象?
- 15. Move构造函数调用基类移动构造函数
- 16. 抛出异常然后调用构造函数?
- 17. 在基类构造函数中构造对象?
- 18. 类构造函数无法抛出类加载异常
- 19. 构造函数可以抛出运行时异常吗?
- 20. 基类构造函数在派生类构造函数之前真的调用
- 21. 从构造函数中抛出异常在C++中
- 22. 通过__init__构造对象并忽略构造函数异常
- 23. 如果基类构造函数不是constexpr,我可以构造派生类constexpr的构造函数吗?
- 24. 如何从枚举构造函数中抛出异常?
- 25. CLR:如果构造函数失败,它总是会抛出异常?
- 26. 用异常抛出构造函数初始化对象的正确方法
- 27. *这会调用构造函数吗?
- 28. 在C++中抛出后调用析构函数吗?
- 29. 未调用基类构造函数?
- 30. 要我试试... catch块在析构函数中,如果我知道我的函数不会抛出异常
我不记得 - 如果你没有发现异常,是保证被调用的基类析构函数,还是作为“堆栈展开”的一部分计算,因此它是否实现定义它是否发生或不在未捕获的异常? – 2010-09-21 10:24:10
@Steve:如果没有捕获,我的实现不会破坏基础,所以我猜*它不能保证,但是谁知道......:-) – fredoverflow 2010-09-21 10:31:49
这就是为什么把一个catch和re-throw放在main中强制堆栈被正确解开是个好主意。 – 2010-09-21 10:41:50