c++ - 在 catch block 异常中无意义地使用引用传递语法?

标签 c++ exception pass-by-reference

我的示例代码:

#include<iostream>
using namespace std;

class Test{ public: int set;};
Test T;

int main()
{
    T.set = 100;
    try{
        throw T;
    }
    catch(Test &T)
    {
        T.set = 0;
    }
    cout<<T.set<<endl;
    return 1;
}

在这里,我通过引用捕获抛出的 T 对象,并在 catch block 中修改它的值。为什么 T 对象在 catch block 之后仍然打印 100?在这种情况下,引用语法比按值传递有什么用?

编译器:gcc 5.1.0

最佳答案

您正在通过引用捕获异常对象,但没有将其抛出。

异常总是“按值抛出”,因为它们必须分配到进程内存的一个特殊区域,该区域不受堆栈展开影响的影响。

[C++14: 15.1/3]: Throwing an exception copy-initializes (8.5, 12.8) a temporary object, called the exception object. The temporary is an lvalue and is used to initialize the variable declared in the matching handler (15.3). [..]

这是一条通用规则,旨在说明更常见的情况,其中 T 实际上是 try block 本身或其封装函数的本地。如果不复制它,就不可能从调用范围中捕获它。

We catch the exception object by reference这样您就不会不必要地再次复制已经复制的T。当您的异常处于继承层次结构中时,它还可以防止切片。有时人们用它来改变异常对象,然后再将其重新抛出到调用范围,尽管这似乎很少见。

通过 reference-to-const 捕获它与通过 reference-to-const 捕获任何其他事物具有相同的好处:它确保您不会改变异常.如果您不重新抛出它,那么这里没有任何实际好处,但如果像我一样,您默认编写 const 作为防止错误的故障保险,没有理由使用它。

关于c++ - 在 catch block 异常中无意义地使用引用传递语法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31638063/

相关文章:

作为函数参数传递的 Java 对象

c++ - 我在关于 C++ 的陈述中遗漏了什么吗?

c++ - 如何对 float 数组使用基数排序?

python-3.x - 循环时Python3缺少异常

java - 这两种方法有什么区别

c - 将在函数中创建的字符串分配给在 main 中创建的 typedef 结构数组

c++ - GDB 显示没有来自带有调试符号的应用程序的回溯

c++ - 我应该为一组指针使用 std::set 或 std::unordered_set 吗?

python - 如何避免异常处理的重复?

c++ - 使用 GDB 从核心文件调试 C++