我阅读了“编程:使用C ++的原理与实践”一书( Bjarne Stroustrup )。有时作者写道:
catch (runtime_error e)
但有时他写道:
catch (runtime_error& e)
据我所知,第一个变体创建了源的副本,但第二个变量使用了链接。还是我弄错了?这对于这种情况下的“捕获”不重要吗?
答案 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)
你应该总是通过引用抓住;绝对没有理由抓住价值。
不要相信所写的一切。 ; - )