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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 20:38:06  来源:igfitidea点击:

catching std::exception by reference?

c++

提问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::exceptionor 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.

这里使用对异常的引用可以减少创建的临时对象,也可以保持多态性。