我有一个愚蠢的问题。我读了这篇关于std :: exception http://www.cplusplus.com/doc/tutorial/exceptions/
的文章在catch (exception& e)
上,它说:
我们已经放置了一个通过引用捕获异常对象的处理程序(请注意&符号后面的&符;),这样也会捕获派生自异常的类,就像myexception类的myex对象一样。
这是否意味着使用“&”你还可以捕获父类的异常?我想&是在std :: exception中预定义的,因为最好将e(std :: exception)作为引用传递给对象。
答案 0 :(得分:55)
将&
与异常一起使用的原因并不是避免slicing的多态性。如果您不使用&
,C ++将尝试将抛出的异常复制到新创建的std::exception
中,可能会丢失该过程中的信息。例如:
#include <stdexcept>
#include <iostream>
class my_exception : public std::exception {
virtual const char *what() const throw() {
return "Hello, world!";
}
};
int main() {
try {
throw my_exception();
} catch (std::exception e) {
std::cout << e.what() << std::endl;
}
return 0;
}
这将打印std::exception
(在我的情况下,St9exception
)而不是Hello, world!
的默认消息,因为切片会丢失原始异常对象。如果我们将其更改为&
:
#include <stdexcept>
#include <iostream>
class my_exception : public std::exception {
virtual const char *what() const throw() {
return "Hello, world!";
}
};
int main() {
try {
throw my_exception();
} catch (std::exception &e) {
std::cout << e.what() << std::endl;
}
return 0;
}
现在我们看到Hello, world!
。
答案 1 :(得分:8)
这是否意味着使用“&amp;”你还可以捕获父类的异常吗?
不,这不会增加从中捕获异常的范围(例如,从包含try / catch代码的类的父类)。
与按值捕获(catch(std::exception e)
而不是&
相比,它也不会增加可捕获的异常类型 - 您仍将捕获每个异常{{1或者从中衍生出来。)
它增加的是捕获异常时实际获得的数据量。
如果抛出的异常派生自std::exception
,并且您按值捕获它,那么您将抛弃该异常类中的任何额外行为。由于polymorphism,它会在异常类上中断Slicing。
一个例子:
std::exception
答案 2 :(得分:2)
否&
绝对不会影响异常处理程序的多态性。他们的措辞很差,似乎表明&
在某种程度上是负责任的。不是这种情况。你是对的,&
只是通过引用传递,这有点效率。
同样作为一般规则, you should really try to avoid cplusplus.com 。
答案 3 :(得分:0)
在此处使用对异常的引用可以减少创建的临时对象,并且还可以保持多态性。