c++ - throw 和 throw 与捕获异常的 arg 有什么区别?

标签 c++ exception try-catch throw

想象两段相似的代码:

try {
  [...]
} catch (myErr &err) {
  err.append("More info added to error...");
  throw err;
}

try {
  [...]
} catch (myErr &err) {
  err.append("More info added to error...");
  throw;
}

这些实际上是相同的,还是在某些微妙的方面有所不同?例如,第一个是否会导致运行复制构造函数,而第二个可能会重用相同的对象来重新抛出它?

最佳答案

根据您如何安排异常层次结构,通过在 throw 语句中命名异常变量来重新抛出异常可能切片原始异常对象。

无参数 throw 表达式将抛出当前异常对象并保留其动态类型,而带参数的 throw 表达式将根据 static 参数的类型向 抛出

例如

int main()
{
    try
    {
        try
        {
            throw Derived();
        }
        catch (Base& b)
        {
            std::cout << "Caught a reference to base\n";
            b.print(std::cout);
            throw b;
        }
    }
    catch (Base& b)
    {
        std::cout << "Caught a reference to base\n";
        b.print(std::cout);
    }

    return 0;
}

如上所写,程序会输出:

Caught a reference to base
Derived
Caught a reference to base
Base

如果 throw b 被替换为 throw,那么外部 catch 也会捕获最初抛出的 Derived 异常。如果内部类通过值而不是通过引用捕获 Base 异常,这仍然成立 - 尽管这自然意味着原始异常对象无法修改,因此对 b 的任何更改> 不会反射(reflect)在外部 block 捕获的 Derived 异常中。

关于c++ - throw 和 throw 与捕获异常的 arg 有什么区别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1481612/

相关文章:

java - 让异常在调用堆栈中向上移动有什么值(value)?

php - 如何在try/catch语句laravel中记录错误?

javascript - 如何使用 WebDriverJS 捕获 Selenium 错误

java - 如何捕获事件调度线程 (EDT) 异常?

c++ - const_cast 是如何工作的?

c++ - 有 new 的异常和没有 new 运算符的异常

c++ - 使 std::thread 异常安全的最简单方法

c++ - 运行时函数模板类型推导

c++ - 使用 char* 时程序崩溃

c++ - 接收器参数和异常