C++ 通过引用捕获 std::exception ?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6755991/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
catching std::exception by reference?
提问by user853069
I have a silly question. I read this article about std::exception http://www.cplusplus.com/doc/tutorial/exceptions/
我有一个愚蠢的问题。我读了这篇关于 std::exception http://www.cplusplus.com/doc/tutorial/exceptions/的文章
On catch (exception& e)
, it says:
在catch (exception& e)
,它说:
We have placed a handler that catches exception objects by reference (notice the ampersand & after the type), therefore this catches also classes derived from exception, like our myex object of class myexception.
我们已经放置了一个通过引用捕获异常对象的处理程序(注意类型后面的&符号),因此这也捕获了从异常派生的类,就像我们的 myex 类 myexception 对象。
Does this mean that by using "&" you can also catch exception of the parent class? I thought & is predefined in std::exception because it's better to pass e (std::exception) as reference than object.
这是否意味着通过使用“&”还可以捕获父类的异常?我认为 & 是在 std::exception 中预定义的,因为最好将 e (std::exception) 作为引用传递而不是对象。
回答by bdonlan
The reason for using &
with exceptions is not so much polymorphism as avoiding slicing. If you were to not use &
, C++ would attempt to copy the thrown exception into a newly created std::exception
, potentially losing information in the process. Example:
使用&
with 异常的原因与其说是避免切片,不如说是多态性。如果您不使用&
,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;
}
This will print the default message for std::exception
(in my case, St9exception
) rather than Hello, world!
, because the original exception object was lost by slicing. If we change that to an &
:
这将打印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;
}
Now we do see Hello, world!
.
现在我们确实看到了Hello, world!
。
回答by Merlyn Morgan-Graham
Does this mean that by using "&" you can also catch exception of the parent class?
这是否意味着通过使用“&”还可以捕获父类的异常?
No, this doesn't increase the scope of where you will catch exceptions from (e.g. from the parent class of the class that contains the try/catch code).
不,这不会增加您将从中捕获异常的范围(例如,来自包含 try/catch 代码的类的父类)。
It also doesn't increase the types of exceptions that can be caught, compared to catching by value (catch(std::exception e)
without the &
- you'll still catch each exception that either is std::exception
or derives from it).
与按值捕获相比,它也不会增加可以捕获的异常类型(catch(std::exception e)
如果没有&
- 您仍然会捕获每个异常std::exception
或从它派生的异常)。
What it increases is the amount of data that you will actually get when you catch the exception.
它增加的是捕获异常时实际获得的数据量。
If an exception is thrown that derives from std::exception
, and you catch it by value, then you are throwing out any extra behavior in that exception class. It breaks polymorphismon the exception class, because of Slicing.
如果抛出源自 的异常std::exception
,并且您按值捕获它,那么您将抛出该异常类中的任何额外行为。由于Slicing,它打破了异常类的多态性。
An example:
一个例子:
class MyException : public std::exception
{
public:
virtual const char* what() const
{
return "hello, from my exception!";
}
};
// ...
try
{
throw MyException();
}
catch(std::exception& e)
{
// This will print "hello, from my exception!"
std::cout << e.what() << "\n";
}
// ...
try
{
throw MyException();
}
catch(std::exception e)
{
// This will print "Unknown exception"
std::cout << e.what() << "\n";
}
回答by Chris Eberle
No the &
has absolutely no bearing on the polymorphic nature of exception handlers. Their wording is very poor, it does seem to indicate that the &
is somehow responsible. This is not the case. You are correct, &
just passes by reference which is a tad more efficient.
不,&
绝对与异常处理程序的多态性质无关。他们的措辞很糟糕,似乎确实表明该&
负责。不是这种情况。你是对的,&
只是通过引用传递,这样效率更高。
Also as a general rule, you should really try to avoid cplusplus.com.
同样作为一般规则,你应该尽量避免 cplusplus.com。
Updated link:What's wrong with cplusplus.com
更新链接:cplusplus.com 有什么问题
回答by Hyman
Using reference to exception here can reduce the temporary objects created, and it can also keep the polymorphism.
这里使用对异常的引用可以减少创建的临时对象,也可以保持多态性。