【问题标题】:Are static objects deleted when an exception is thrown, or just local objects?抛出异常时是删除静态对象还是仅删除本地对象?
【发布时间】:2011-09-19 01:37:18
【问题描述】:
#include <iostream>
#include <exception>
using std::cout;
using std::endl;
class test
{
 public:
    test()
    {
        cout<<"constructor called"<<endl;
    }
    ~test()
    {
        cout<<"destructor called"<<endl;
    }
    void fun(int x)
    {
       throw x;
    }
};

int main()
{
    try
    {
        static test k;          
        k.fun(3);
    }
    catch(int k)
    {
        cout<<"exception handler"<<endl;
    }
}

当抛出异常时,然后在堆栈展开过程中,我认为只有本地对象被破坏,而不是静态或堆对象。如果这是真的,我不确定为什么要调用类(测试)析构函数?谢谢。

【问题讨论】:

    标签: c++ exception-handling object-destruction


    【解决方案1】:

    在 main 退出后调用测试析构函数。

        catch(int k)
        {
            cout<<"exception handler"<<endl;
        }
        // Added this line
        std::cout << "Main Exiting\n";
    }
    

    正在测试

    > g++ test.cpp
    > ./a.out
    constructor called
    exception handler
    Main Exiting
    destructor called
    

    Static(静态存储持续时间对象)在 main 退出后按创建的相反顺序销毁。

    【讨论】:

      【解决方案2】:

      调用析构函数是因为您的程序正在退出。只有自动存储持续时间的对象(绝对不是堆栈对象或堆对象)被销毁。

      【讨论】:

      • 你的意思是“...静态对象或堆对象”
      【解决方案3】:

      运行这段代码时,我得到了输出

      constructor called
      exception handler
      destructor called
      

      这是有道理的。首先调用静态test 对象的构造函数。当异常被抛出时,它被异常处理程序捕获并打印消息。最后,当程序终止时,静态test 对象的析构函数被调用。

      假设异常实际上在某处被捕获,异常只会导致具有自动持续时间的变量(即本地变量)的生命周期结束。异常不会破坏具有动态持续时间的对象(即使用new 分配的对象),但如果动态分配对象的构造函数中发生异常,则内存将被回收,因为否则无法取回内存。同样,static 对象不会被销毁,因为它们应该在整个程序中持续存在。如果它们被清理,如果对这些对象的引用在程序中传递,则可能会导致问题。

      希望这会有所帮助!

      【讨论】:

      • 是的,你是对的,但是如果构造函数在动态分配内存的过程中发生异常,那么就不需要回收内存,因为如果构造函数没有完全构造,它就不会调用删除。
      猜你喜欢
      • 2013-02-26
      • 1970-01-01
      • 1970-01-01
      • 2018-07-28
      • 1970-01-01
      • 1970-01-01
      • 2015-12-14
      • 1970-01-01
      • 2016-07-18
      相关资源
      最近更新 更多