ren*_*nan 1 c++ inheritance constructor destructor exception
我有一些问题来处理派生类中的构造函数异常.当派生类构造函数抛出错误时,父类已经分配了一些对象.是否会调用父类析构函数?
例:
class A
{
A() { /* Allocate some stuff */ };
virtual ~A() { /* Deallocate stuff */ };
};
class B : public A
{
B()
{
/* Do some allocations */
...
/* Something bad happened here */
if (somethingBadHappened)
{
/* Deallocate B Stuff */
...
/* Throws the error */
throw Error; /* Will A destructor be called? I know B destructor won't */
};
};
~B() { /* Deallocate B Stuff */ };
}
Run Code Online (Sandbox Code Playgroud)
我想知道做以下事情是否是一个好主意:
B()
{
/* Do some allocations */
...
/* Something bad happened here */
if (somethingBadHappened)
{
/* Deallocate B Stuff */
this->~B();
/* Throws the error */
throw Error; /* Will A destructor be called? I know B destructor won't */
};
};
Run Code Online (Sandbox Code Playgroud)
如果没有,最新情况是什么?
异常将导致堆栈展开到正确捕获异常的位置.这意味着在抛出异常之前在范围中创建的任何对象都将被破坏,包括本示例中的基类对象.
试试这个:
#include <iostream>
class A
{
public:
A() { std::cout << "A::A()\n";}
~A() {std::cout << "A::~A()\n";}
};
class B : public A
{
public:
B()
{
std::cout << "B::B()\n";
throw 'c';
}
// note: a popular point of confusion --
// in this example, this object's destructor
// WILL NOT BE CALLED!
~B()
{
std::cout << "B::~B()\n";
}
};
int main()
{
try
{
B b;
}
catch(...)
{
std::cout << "Fin\n";
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
输出应为:(注意B::~B()不要调用)
A::A()
B::B()
A::~A()
Fin
Run Code Online (Sandbox Code Playgroud)
只要您不尝试释放尚未分配的资源,就可以安全地手动调用析构函数.更好地包裹这些资源在某种类型的RAII容器(std::auto_ptr,boost::shared_ptr等),以避免调用析构函数的必要性.
Mooing Duck提供了一个非常好的例子,说明了在构造函数中抛出异常时堆栈展开的工作方式:

| 归档时间: |
|
| 查看次数: |
2185 次 |
| 最近记录: |