我应该以哪种方式捕获异常

Which way should I catch an exception?

本文关键字:方式 捕获异常 我应该      更新时间:2023-10-16

我有一个带有自定义异常的模板类:

MyClass<T>::MyException;

当使用我的类时,我只关心异常是否被抛出,这样我就可以通过编程来处理它。因此,当我捕获异常时,我不必费心为它命名。

try {
   MyClass<T>::MyMethod ();
} catch (typename MyClass<T>::MyException) {
   //Act appropriately
}

我想知道当我添加引用操作符时是否有任何不同,例如

} catch (typename MyClass::MyException &) {

在这两种情况下,除了识别类型之外,我最终都不会使用捕获的异常。两者之间是否存在权衡或性能损失?

按值捕获创建异常对象的副本,无论是否使用它。所以不要。总是通过引用来捕获。没有理由按值捕获。

顺便说一句,这里的typename关键字是多余的,因为没有涉及任何模板。

在第一种情况下:

catch (typename MyClass:MyException)

将在捕获时调用复制构造函数。同样,如果你从MyException得到了另一个异常,它将被切片。

当你这样做的时候:

catch (typename MyClass:MyException &)

你不会引起复制(所以它更有效),你可以安全地捕获派生的异常。

您应该始终通过引用捕获异常。这只是一个好习惯

然而,在这种特殊情况下,我认为这无关紧要。没有切片问题,因为没有命名捕获的异常对象,所以没有可以访问的成员。异常是否被复制两次应该无关紧要——这只是一个异常的情况,复制是便宜的(如果抛出是正常程序流的一部分,那么无论如何你都有一个更大的问题)。

关键是:按价值捕获也买不到任何东西。在源代码中保存一个字符不算数:)恰恰相反,它会在将来创建一个可能的错误来源。