gpt4 book ai didi

c++ - C++ 中的异常处理程序 catch(...)

转载 作者:行者123 更新时间:2023-12-05 03:30:23 25 4
gpt4 key购买 nike

我知道 C++ 中的异常处理程序 catch(...) 可以处理任何类型的异常。我想知道如果它必须处理某种类类型的异常会发生什么 - 该类的对象是通过引用还是通过值传递给此处理程序?

这是有助于理解这一点的代码。当“内部尝试”抛出类型 B 的异常时,将使用 B 类的默认构造函数创建 B 类的未命名临时对象。当我运行该程序时,根本不会调用 B 类的复制构造函数,而这个 B 类的未命名临时对象只有在执行“Outer try 3”后才会被销毁,这意味着该对象一直向后传播到“Outer try 3”。所以我的猜测是对象通过引用传递给 catch(...) 处理程序,但我想看看这是否是正确的推理。

    #include <iostream>

using namespace std;

class A {
public:
A() {
cout << "Default constructor of class A" << endl;
}
A(const A& a) {
cout << "Copy constructor of class A" << endl;
}
A(A&& a) noexcept {
cout << "Move constructor of class A" << endl;
}
~A() {
cout << "Destructor of class A" << endl;
}
};

class B {
public:
B() {
cout << "Default constructor of class B" << endl;
}
B(const B& b) {
cout << "Copy constructor of class B" << endl;
}
B(B&& b) noexcept {
cout << "Move constructor of class B" << endl;
}
~B() {
cout << "Destructor of class B" << endl;
}
};

int main() {
try {
try {
try {
try {
throw A();
}
catch (A a) {
cout << "Inner try" << endl;
throw B();
}
}
catch (...) {
cout << "Outer try 1" << endl;
throw;
}
}
catch (...) {
cout << "Outer try 2" << endl;
throw;
}
}
catch (...) {
cout << "Outer try 3" << endl;
}
}

最佳答案

当您抛出异常时,异常对象 是从操作数到 throw 创建的.它是以未指定方式存储的对象。

当到达异常的匹配处理程序并且处理程序不是 ... 时,然后从异常对象初始化处理程序的参数。

基本上,如果您声明一个 catch参数作为非引用类型,您将在处理程序中获得异常对象(或基类子对象)的拷贝。这就是您在 A 中看到的内容处理程序以及为什么调用复制构造函数。拷贝一直存在,直到处理程序退出。如果您将参数声明为引用类型,那么您将获得对异常对象的引用,如果您重新抛出异常,它将始终引用同一个对象。

重新抛出 throw;实际上并没有对 catch 的参数做任何事情条款。它只是导致异常处理继续搜索 catch条款和堆栈展开。异常对象还是一样。

如果处理程序是 catch(...),这一切都不会改变.在处理程序中没有要初始化的变量(引用与否),但是 throw;将重新抛出并继续搜索具有相同异常对象的处理程序。

当处理程序退出而不重新抛出异常时,异常对象将被销毁。这发生在你最外面的 catch 的末尾对于 B异常对象并在最内层的末尾 catch对于 A异常对象。 (您得到两次对 A 的析构函数调用,一次针对 catch 参数,另一次针对异常对象。)

关于c++ - C++ 中的异常处理程序 catch(...),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70821456/

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