抛出异常时是删除静态对象还是仅删除本地对象?

发布于 2024-11-16 11:45:06 字数 586 浏览 4 评论 0原文

#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;
    }
}

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

#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;
    }
}

When the exception is thrown, then during the stack unwinding process, I think only local objects are destroyed, not static or heap objects. If this is true, I am not sure why the class (test) destructor is called? Thanks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

一身软味 2024-11-23 11:45:06

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退出后按照创建的相反顺序被销毁。

The test destructor is called after main exits.

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

Now testing

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

Static (static storage duration objects) are destroyed in the reverse order of creation after main exits.

咿呀咿呀哟 2024-11-23 11:45:06

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

The destructor is called because your program is exiting. Only objects of automatic storage duration (that is definitely not stack objects or heap objects) are destroyed.

何止钟意 2024-11-23 11:45:06

输出

constructor called
exception handler
destructor called

运行此代码时,我得到了有意义的 。首先调用静态 test 对象的构造函数。当抛出异常时,异常处理程序会捕获异常并打印消息。最后,当程序终止时,调用静态 test 对象的析构函数。

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

希望这有帮助!

When running this code, I get the output

constructor called
exception handler
destructor called

Which makes sense. The constructor for the static test object is invoked first. When the exception is thrown, it is caught by the exception handler and the message is printed. Finally, when the program terminates, the destructor for the static test object is invoked.

Exceptions only cause the lifetimes of variables with automatic duration (i.e. locals) to end, assuming that the exception is actually caught somewhere. Exceptions will not destroy objects with dynamic duration (i.e. things allocated with new), though if an exception occurs in a constructor for a dynamically-allocated object the memory will be reclaimed, since there's otherwise no way to get the memory back. Similarly, static objects are not destroyed, since they're supposed to last for the entire program. If they were cleaned up, it could cause problems if references to those objects had been passed around the program.

Hope this helps!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文