可能是重复问题:
如何在C++中通过指针捕获异常
我通常通过值来捕获异常,例如:
try{
...
}
catch(CustomException e){
...
}
但我遇到了一些代码,它使用catch(CustomException &e)
而不是使用catch(CustomException e)
。这是a)正确的、b)错误的还是c)灰色地带的?
可能是重复问题:
如何在C++中通过指针捕获异常
我通常通过值来捕获异常,例如:
try{
...
}
catch(CustomException e){
...
}
但我遇到了一些代码,它使用catch(CustomException &e)
而不是使用catch(CustomException e)
。这是a)正确的、b)错误的还是c)灰色地带的?
C++中处理异常的标准做法是...
抛出值,引用捕获
通过值进行捕获在面对继承层次结构时会带来问题。假设你的例子有另一个类型MyException
,它从CustomException
继承并覆盖了错误代码等项目。如果抛出了MyException
类型,您的catch块会导致其被转换为一个CustomException
实例,这将导致错误代码更改。
throw
语句中的参数应该在堆栈上,并且应该在解除堆栈时被销毁。使用 throw new
是错误的。 - Potatoswatterthrow;
在其他地方使其可见(从而打破我的类比)。 - Daniel Earwicker如果你使用值捕获方式来处理异常,当捕获到派生类型的异常时,会截取为你所捕获类型的异常对象。
这可能会对catch块中的逻辑造成影响,但没有理由不使用const引用方式进行捕获。
请注意,如果在catch块中使用throw;
而没有参数,不管你是捕获了一个被截取过的副本还是一个异常对象的引用,原始异常都将被重新抛出。
base &operator=(const base &other)
中将派生对象隐式转换为 base &
引用,所以赋值运算将派生类视为基类的一样处理,并没有什么神奇的切片或转移。你只是在调用一个函数。 - Injektilo如果您不想处理异常,通常应使用一个const引用:catch (const CustomException& e) { ... }
。编译器处理抛出对象的生命周期。
在 (CustomException e)
中创建了 CustomException 的新对象... 因此它的构造函数将被调用,而在 (CustomException &e) 中,只是引用... 不会创建新对象,也不会调用构造函数... 因此前者有点多余... 后者更好使用...
catch(CustomException const &e)
... - Alexis Wilke