sách gpt4 ai đã đi

ngoại lệ c++ trong hàm hủy

In lại 作者:塔克拉玛干 更新时间:2023-11-02 23:50:40 hai mươi bốn 4
mua khóa gpt4 Nike

从其他线程,我知道我们不应该在析构函数中抛出异常!但是对于下面的例子,它确实有效。这是否意味着我们只能在一个实例的析构函数中抛出异常?我们应该如何理解这个代码示例!

#include 
sử dụng không gian tên std;
class A {
công cộng:
~A() {
thử {
printf("exception in A start\n");
throw 30;
printf("exception in A end\n");
}catch(int e) {
printf("catch in A %d\n",e);
}
}
};
class B{
công cộng:
~B() {
printf("exception in B start\n");
throw 20;
printf("exception in B end\n");
}
};
int main(void) {
thử {
A a;
B b;
}catch(int e) {
printf("catch in main %d\n",e);
}
trả về 0;
}

输出是:

exception in B start
exception in A start
catch in A 30
catch in main 20

1 Câu trả lời

C++17 之前的最佳实践是不要让异常从析构函数中传播。如果析构函数包含 ném 表达式或调用可能抛出的函数,只要捕获并处理抛出的异常而不是从析构函数中转义就可以了。所以你的 A::~A 没问题。

B::~B,您的程序在 C++03 中没有问题,但在 C++11 中却不行。规则是,如果您Thực ra让异常从析构函数中传播出来,并且该析构函数是针对一个自动对象的,该对象直接被堆栈展开销毁,那么std::terminate 将被调用。由于 b 没有作为栈展开的一部分被销毁,从 B::~B 抛出的异常将被捕获。但在 C++11 中,B::~B 析构函数将被隐式声明为 noexcept,因此,允许异常从中传播出去将调用 std::terminate 无条件。

要允许在 C++11 中捕获异常,您可以这样写

~B() noexcept(false) {
// ...
}

不过,在堆栈展开期间可能会调用 B::~B 的问题——在这种情况下,std::terminate 将是叫。因为在 C++17 之前,没有办法判断是否是这种情况,所以建议永远不要让异常传播到析构函数之外。遵守这条规则,你会没事的。

在 C++17 中,可以使用 std::uncaught_exceptions() 检测对象是否在堆栈展开期间被销毁。但你最好知道自己在做什么。

关于析构函数中的c++异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41174167/

hai mươi bốn 4 0
Bài viết được đề xuất: c++ - C++14 中的尾随返回类型
Bài viết được đề xuất: linux - 运行 cron 不到一分钟 - laravel
Bài viết được đề xuất: python - 如何在 Python virtualenv 中安装 gevent?
Bài viết được đề xuất: c++ - 两个相乘的每个子集的加法
Giấy chứng nhận ICP Bắc Kinh số 000000
Hợp tác quảng cáo: 1813099741@qq.com 6ren.com