可能重复:
catch exception by pointer in C++C++ catch块 - 通过值或引用捕获异常?
我总是通过值捕获异常。例如
try{
...
}
catch(CustomException e){
...
}
但我碰到一些代码,而不是catch(CustomException &e)
。这是a)罚款b)错误c)灰色地带?
可能重复:
catch exception by pointer in C++C++ catch块 - 通过值或引用捕获异常?
我总是通过值捕获异常。例如
try{
...
}
catch(CustomException e){
...
}
但我碰到一些代码,而不是catch(CustomException &e)
。这是a)罚款b)错误c)灰色地带?
在C++异常标准的做法是...
投掷的价值,渔获参考
通过值捕获在继承层次面对的问题。假设您的示例中有另一个类型MyException
,它继承自CustomException
,并覆盖像错误代码这样的项目。如果MyException
类型被抛出,您的catch块将导致它被转换为CustomException
实例,这将导致错误代码发生变化。
参考
为此,我会补充:通过const引用赶上。不幸的是,你可以抛出一个const对象,并用非const引用来捕获它。为了避免这种无声的“抛弃”const,总是捕获一个const引用,并确保你的异常类型具有const正确的访问器。 – 2010-03-26 10:01:13
@Danial Earwicker:为什么“不幸”你可以通过非const引用捕获? 异常对象总是被复制,所以无论你抛出什么'对象',你都不能影响任何catch块中的原始对象,因为抛出的'object'实际上只是一个初始化器。 const没有抛弃const;异常对象总是非常量的,非易失性的。通过非const引用允许捕获使中间catch块能够将信息添加到异常。它不常用,但如果你需要的话,它就在那里。 – 2010-03-26 10:06:38
你可以提供一个参考,如果你想接受的答案:) – 2010-03-26 10:07:12
按值捕获将分片如果异常是派生类型的异常对象,您捕获的类型。
这可能或可能不会影响你的catch块的逻辑,但没有什么理由不被const引用捕获。
请注意,如果throw;
在catch块中没有参数,则无论是否捕获切片副本或对异常对象的引用,都会重新生成原始异常。
在这种情况下,我不熟悉术语* slice *。 – 2012-11-27 16:59:49
我认为“切片”是一个用来引用传递语言的人喜欢使用的术语。如果你将派生对象赋值给它的基类型,这个想法是“切断”对象的一部分,对我来说这似乎是一种误导性的方式,因为实际发生的事情是,在基类的复制赋值运算符“ base&operator =(const base&other)'派生对象被隐式转换为'base&'引用,所以赋值将派生类视为基类。有没有魔术切片或转移的东西,你正在调用一个函数 – Injektilo 2013-05-16 08:30:31
除非你想用异常不甘示弱,你通常应该使用const引用:catch (const CustomException& e) { ... }
。编译器处理抛出的对象的生命周期。
在(CustomException e)
CustomException的新对象被创建...所以它的构造函数将被调用,而在(CustomException & e)它只会引用...不创建新对象并且不会调用构造函数...所以正式的是一点点的开销......后来更好用...
请注意,正确的引用也是常量:'catch(CustomException const&e)'... – 2015-02-07 01:27:15
不应该被标记为重复 - 捕获ptr的例外与通过引用或值捕获不同。 – wcochran 2017-02-10 20:23:31