gpt4 book ai didi

c++ - try block 会保护局部变量的破坏吗?

转载 作者:行者123 更新时间:2023-11-30 02:34:50 26 4
gpt4 key购买 nike

class A
{
public:
~A();
};
A::~A()
{
std::cout<<"Destructor!!!\n"<<std::endl;
std::exception e;
throw e;
}
void main()
{
try
{
A a;
//A a1,a2;//This gives out two lines of "Destructor!!!" then the program terminates
}
catch(std::exception)
{
std::cout<<"Caught!!!\n"<<std::endl;
}
}

我知道在析构函数中发出异常是一种不好的做法。但它并不违法。上面的程序进入了 catch block 。 try block 似乎在保护局部变量的销毁。但是,如果我取消注释代码,它会给出一些不同的东西。在这种情况下,似乎第一个异常没有得到处理,终止是由多个异常引起的。现在我不确定是否保护了令人兴奋的函数时局部变量的破坏。我正在使用 VS2005 顺便说一下。

最佳答案

try/catch block 将只处理一个异常。如果您在一个 block 中构造了两个或多个 A 类型的对象,则这些对象中的每一个的析构函数都会抛出异常。可以处理第一个抛出的异常(来自最后创建/首先销毁的对象)。但是,在到达处理程序之前,所有其他本地对象都将被销毁。当 block 中有另一个 A 对象时,它也将被销毁,抛出异常,瞧,有两个异常。当析构函数外有两个未处理的异常时,系统调用需要终止程序的 std::terminate()

在 C++11 中,所有析构函数都被隐式定义为 noexceptnoexcept(true)(两者是等价的)。此更改的原因是默认情况下,构建和销毁临时对象的移动应该是 noexcept。如果您想使用 C++11 抛出析构函数,您需要将析构函数声明为 noexcept(false),例如:

class A {
public:
~A() noexcept(false) { throw std::exception(); } // still a Bad Idea!!!
// ...
};

当从析构函数中抛出异常时,您实际上需要确保在处理现有异常时对象不会因堆栈展开而被销毁。在析构函数中可以有异常,只要没有异常逃脱析构函数。

在实践中,没有安全的方法可以知道对象是否因堆栈展开而被销毁。尽管从语言的角度来看是合法的,但最好永远不要从析构函数中抛出。

关于c++ - try block 会保护局部变量的破坏吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34277903/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com