gpt4 book ai didi

c++ - 删除从析构函数调用的抛出析构函数

转载 作者:搜寻专家 更新时间:2023-10-31 01:29:47 25 4
gpt4 key购买 nike

我知道 C++ 中的当前规则是这样说的:

if a destructor throws while already stack unwinding because of a exception then std::terminate is called.

在探索为什么规则是这样的时候,我遇到了下面代码中描述的情况。

  1. X 的析构函数抛出。

  2. Y 在它自己的析构函数中删除一个 X

  3. 因此 Y 的析构函数抛出。

我不清楚 Y 抛出 (3.) 是否应该按照标准规则触发 std::terminate。我希望它不会,并且针对 gcc 的测试如我希望的那样运行。

熟悉标准法律术语的人可以澄清一下吗? (3.) 是否应该触发 std::terminate

#include <iostream>

struct X {
~X() noexcept(false) {
std::cout << "Destroying X\n";
throw std::runtime_error("Exception");
}
};

struct Y {
X * x_;

explicit Y(X * x) : x_{x} { }

~Y() noexcept(false) {
std::cout << "Destroying Y\n";
delete x_;
}
};

int main() {
try {
Y y(new X());
std::cout << "Living\n";
}
catch (const std::exception & e) {
std::cout << "Caught " << e.what() << '\n';
}
}

使用 g++ 版本 5.4.0-6ubuntu1~16.04.9 和 --std=c++17 我得到:

Living
Destroying Y
Destroying X
Caught Exception

最佳答案

标准在[except.terminate]p1.4中说:

  • when the destruction of an object during stack unwinding terminates by throwing an exception, or

2) 发生是因为 y 超出范围。 1) 抛出异常,开始堆栈展开。在堆栈展开期间,更具体地说是在销毁 Y 时 - 即 2)。它抛出一个异常,因此满足该点并调用 std::terminate

这正是您的代码正在做的事情,除了重要的一点:在堆栈展开期间。堆栈展开不会在范围结束时发生,它只会在抛出异常并超出抛出的当前范围时发生。

Y 没有因为异常而被销毁。添加 throw 1; 以查看对 std::terminate 的调用。

因此,该条款不适用,您的代码确实有效。

关于c++ - 删除从析构函数调用的抛出析构函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49290248/

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