当异常在构造函数中抛出析构函数不调用

当异常在构造函数中抛出析构函数不调用

本文介绍了当异常在构造函数中抛出析构函数不调用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

为什么析构函数在此code调用?

 的#include<升压/ scoped_ptr.hpp>
#包括LT&;&iostream的GT;MyClass类{
提高:: scoped_ptr的< INT> PTR;
上市:
MyClass的():PTR(新INT){* PTR = 0;扔;性病::法院LT&;<MyClass的分配\\ N的; }
〜MyClass的(){性病::法院LT&;<MyClass的解分配\\ N的; }
INT增量(){返回++ * PTR; }
};诠释的main()
{
    提高:: scoped_ptr的< MyClass的> MYINST(新MyClass的);
    性病::法院LT&;< myinst->增量()<<的'\\ n';
    性病::法院LT&;< myinst->增量()<<的'\\ n';
}

修改

从答案,明白当一个异常在构造情况,析构函数将不会被调用。但是,如果异常在main()发生后,即MyClass的对象完全实例化,将MyClass的析构函数被调用?如果没有,那么为什么它是一个智能指针?

添加code

 的#include<升压/ scoped_ptr.hpp>
#包括LT&;&iostream的GT;MyClass类{
    提高:: scoped_ptr的< INT> PTR;
    上市:
    MyClass的():PTR(新INT){* PTR = 0;性病::法院LT&;<MyClass的分配\\ N的; }
    〜MyClass的(){性病::法院LT&;<MyClass的解分配\\ N的; }
    INT增量(){返回++ * PTR; }
};诠释的main()
{
    提高:: scoped_ptr的< MyClass的> MYINST(新MyClass的);
    扔3;
    性病::法院LT&;< myinst->增量()<<的'\\ n';
    性病::法院LT&;< myinst->增量()<<的'\\ n';
}

输出:

  MyClass的分配
扔'诠释'的一个实例后终止叫
中止


解决方案

一个C ++对象的生命周期开始它的构造函数成功完成后进行。结果
由于构造函数调用完成之前抛出异常,你没有一个完整的对象,因此没有析构函数。

香草萨特的很好,引用他:

EDIT 1:
But if the exception happens in the main(), ie after the MyClass object is fully instantiated, will the MyClass destructor be invoked?

Yes, it will be!
That is the purpose of using scoped_ptr, Once an exception is thrown in main, Stack Unwinding would cause all local objects to be deallocated, this means that myinst(which resides on stack) will also be deallocated, which in turn will call the destructor of MyClass.

Refer the Boost doccumentation when in doubt:

EDIT 2:
Why does your edited program crash?
Your program shows crashes because, You throw an exception but you never catch it. when such a scenario occurs an special function called terminate() is called whose default behavior is to call abort().It is implementation defined behavior whether stack is Unwound before terminate() is called in this particular scenario.Seems your implementation doesn't & you should not rely on this behavior as well.

You can modify your program as follows to handle the exception and you should get the behavior you were expecting:

#include <boost/scoped_ptr.hpp>
#include <iostream>

class MyClass {
    boost::scoped_ptr<int> ptr;
    public:
    MyClass() : ptr(new int) { *ptr = 0; std::cout<<"MyClass Allocated\n"; }
    ~MyClass() { std::cout<<"MyClass De-allocated\n"; }
    int increment() { return ++*ptr; }
};

void doSomething()
{
    boost::scoped_ptr<MyClass> myinst(new MyClass);
    throw 3;
}

int main()
{
    try
    {
        doSomething();
    }
    catch(int &obj)
    {
        std::cout<<"Exception Handled";
    }

}


C++03 15.5.1 The terminate() function

这篇关于当异常在构造函数中抛出析构函数不调用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-18 13:55