在scoped_ptr发生异常的情况下未调用析构函数
destructor not called in case of exception with scoped_ptr
我刚刚开始使用c++boost库。我在很多地方读到,当使用scope_ptr时,即使出现异常,对象也总是被销毁。
它们的行为很像内置的C++指针,只是它们会在适当的时候自动删除指向的对象。智能指针在遇到异常时特别有用,因为它们可以确保正确销毁动态分配的对象。
我尝试了以下代码。
#include<boost/scoped_ptr.hpp>
class B
{
public:
B(){ std::cout<< "B constructor calln"; }
~B(){ std::cout<<"B destructor calln"; }
};
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)
没有对B的析构函数的调用。但我使用了scope_ptr,所以它应该调用B的析构函数,或者我错误地解释了scope_ptr。
但如果a用try-catch包围它,那么B的析构函数就会被调用。
try{
A a;
} catch( ... ) {
}
在这种情况下,A的析构函数将被调用,因为在try块中出现异常的情况下,所有本地分配的对象都将从堆栈中删除,并且我的指针被包裹在scoped_ptr的对象中,所以当scoped对象的析构符最终销毁指针时。scope_ptr之所以有用,是因为我们不必显式删除分配的内存,或者我错误地解释了scope_ptr的描述。
在使用scope_ptr 发生异常的情况下,如何调用类B的析构函数
没有匹配的异常处理程序,因此直接调用std::terminate
,在这种情况下不展开堆栈。在main
中放入一个try
/catch
来捕获int
,即使该处理程序重新抛出,您也会看到您的析构函数调用。
C++11§15.1/2:
当抛出异常时,控制权将转移到具有匹配类型的最近处理程序;"最近的"是指控件线程最近为其输入
try
关键字后的复合语句或ctor初始值设定项但尚未退出的处理程序。
和§15.3/9:
如果没有找到匹配的处理程序,则调用函数
std::terminate()
;在对CCD_ 8的调用之前堆栈是否展开是实现定义的。
在线演示
C++在展开堆栈时销毁局部变量(从函数返回,使用return
关键字或有异常),因此它应该看到一个销毁scoped_ptr
的变量。但在您的特殊情况下,异常发生在main
中,因此terminate
将被调用并在C++展开堆栈之前终止您的程序。
void test() {throw 1;}
void main() {
string sMain;
test();
}
在上面的例子中,sMain
不会被破坏,因为调用terminate
:的异常原因
sMain constructed
exception occurred: main has no where to go, and it has no handler to handle
the exception, so it will call `terminate`, but wait we are still at `main`
so we have no stack unwinding here and sMain will never destroyed!!
- 如果 std::vector::clear() 不是静态的,如何在没有实例的情况下调用它?
- C++ - 如何在不调用其属性的情况下调用类?
- C++ 在不释放内存的情况下调用析构函数
- Python在不引用类名的情况下调用类函数
- 为什么在这种情况下调用非常量右值移动构造函数?
- 是否可以在没有显式专用化的情况下调用可变参数模板函数?
- 使用按引用调用时,不能在没有对象的情况下调用成员函数 const
- 您可以在不调用构造函数的情况下调用攻击器吗?
- 命名空间:不能在没有对象的情况下调用成员函数
- 哪些语言将在没有显式桥接的情况下调用C++
- 如何在不重新索引顶点的情况下调用"boost::remove_vertex"?
- C :在没有对象实例的情况下调用非静态成员函数
- 在不实例化的情况下调用不同派生类的虚拟方法
- C 如何在没有错误的情况下调用void函数
- 在MSVC上的数组初始化期间,destructor在不复制或移动构造方的情况下调用
- 在不指定实例化的情况下调用类模板的静态方法的方法
- 为什么INVOKE总是取消引用数据成员,而不是在可能的情况下调用
- 是否可以在不实例化派生类的情况下调用该类的虚拟函数
- 无法在没有对象的情况下调用成员函数(尽管我相信我确实初始化了它)
- 为什么在没有赋值运算符的情况下调用转换构造函数