使用scoped_ptr在异常情况下不调用析构函数

leo*_*dus 6 c++ boost destructor exception scoped-ptr

我刚开始使用c ++ boost库.我在许多地方读过,当使用scoped_ptr时,即使出现异常,对象也总是被销毁.

它们的行为与内置的C++指针非常相似,只是它们会自动删除在适当的时间指向的对象.智能指针在面对异常时特别有用,因为它们可确保正确销毁动态分配的对象.

我试过以下代码.

#include<boost/scoped_ptr.hpp>

class B
{
  public:
    B(){ std::cout<< "B constructor call\n"; }
    ~B(){ std::cout<<"B destructor call\n"; }
};

class A
{
  public:
  boost::scoped_ptr<B> b;
  A():b(new B())  
  {
    throw 1;
  }
};

int main()
{
    A a; return 0;
}

output:
B constructor call
terminate called after throwing an instance of 'int'
Aborted (core dumped)
Run Code Online (Sandbox Code Playgroud)

没有调用B的析构函数.但我使用scoped_ptr所以它应该调用B的析构函数或者我错误地解释了scoped_ptr的使用.

但如果用try catch环绕它,那么就会调用B的析构函数.

try{
  A a;
} catch( ... ) {
}
Run Code Online (Sandbox Code Playgroud)

在这种情况下,A的析构函数将被调用作为所有本地分配的对象,如果try块中的异常从堆栈中删除并且我的指针包含在内部并且scoped_ptr的对象因此当scoped对象的析构函数破坏哪个最终指针.所以scoped_ptr是有用的,因为我们不必显式删除分配的内存或者我错误地解释了scoped_ptr的描述.

如果使用scoped_ptr在异常情况下如何调用B类的析构函数

ild*_*arn 15

没有匹配的异常处理程序,因此std::terminate直接调用,在这种情况下不会展开堆栈.把一个try/ catch放在main那个捕获中int,你会看到你的析构函数调用,即使该处理程序重新抛出.

C++11§15.1/ 2:

抛出异常时,控制权将转移到具有匹配类型的最近处理程序; "nearest"表示最近由控制线程输入并且尚未退出的关键字后面的复合语句ctor-initializer的处理程序try.

和§15.3/ 9:

如果找不到匹配的处理程序,std::terminate()则调用该函数; 在此调用之前是否展开堆栈std::terminate()是实现定义的.

在线演示