通过引用捕获std :: exception?

时间:2011-07-20 01:22:33

标签: c++

我有一个愚蠢的问题。我读了这篇关于std :: exception http://www.cplusplus.com/doc/tutorial/exceptions/

的文章

catch (exception& e)上,它说:

  

我们已经放置了一个通过引用捕获异常对象的处理程序(请注意&符号后面的&符;),这样也会捕获派生自异常的类,就像myexception类的myex对象一样。

这是否意味着使用“&”你还可以捕获父类的异常?我想&是在std :: exception中预定义的,因为最好将e(std :: exception)作为引用传递给对象。

4 个答案:

答案 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

更新了链接: What's wrong with cplusplus.com

答案 3 :(得分:0)

在此处使用对异常的引用可以减少创建的临时对象,并且还可以保持多态性。