'catch'的参数

时间:2013-05-15 11:10:15

标签: c++

我阅读了“编程:使用C ++的原理与实践”一书( Bjarne Stroustrup )。有时作者写道:

catch (runtime_error e)

但有时他写道:

catch (runtime_error& e)

据我所知,第一个变体创建了源的副本,但第二个变量使用了链接。还是我弄错了?这对于这种情况下的“捕获”不重要吗?

4 个答案:

答案 0 :(得分:9)

我希望大多数时候,他会使用:

catch ( runtime_error const& e )

按值捕获和按引用捕获的差异是 与传递值完全相同并通过引用传递 一个函数参数。最重要的区别在于 通过引用捕获时,动态类型可以是 一个派生类型,按值将导致切片(因为 拷贝)。

另外,如果你通过非const引用捕获,并修改 异常对象,然后重新抛出,它是修改后的对象 将传播。

答案 1 :(得分:4)

为了避免不必要的副本和切片,您应该始终通过引用捕获异常。特别是在这种情况下,当您计划重新throw;时。

答案 2 :(得分:3)

按价值追赶

catch (runtime_error e)

与参考文献相比

catch (runtime_error& e)

如果你有(通常是多态的)异常类层次结构,并且想要在单个catch子句中捕获所有派生类型的异常,则使用后者。

例如,标准库中的所有异常类都派生自std::exception,因此您可以执行以下操作:

try {
    int i;
    std::cin >> i;
    switch (i) {
        case 1:  throw std::range_error();
        case 2:  throw std::overflow_error();
        case 3:  throw std::undefflow_error();
        default: throw std::logic_error();
    }
} catch (std::exception& e) {
    // handle all the exceptions the same way,
    // but print a diagnostic message polimorphicaly
    std::cout << "I caught: " << e.what() << '\n';
}

如果通过引用而不是按值捕获,则总是会捕获std::exception,从对象的派生部分切出。

答案 3 :(得分:1)

你应该总是通过引用抓住;绝对没有理由抓住价值。

不要相信所写的一切。 ; - )