C ++中的exception对象范围
C ++中的exception对象的范围是什么? catch处理程序执行后是否超出范围? 另外,如果我创build了一个未命名的exception对象并将其抛出,那么在捕获exception的时候,如果我通过const引用或非const引用来捕获它,那么它是否重要?
当评估一个throw
expression式时,将从expression式的值初始化一个exception对象。 抛出的exception对象从throwexpression式的静态types中忽略任何const
和volatile
限定符。 对于类types,这意味着执行复制初始化 。
exception对象的作用域超出了抛出块的范围。 把它想象成居住在一个特殊的exception区域,离开本地物体所在的正常调用堆栈的一边。
在一个catch
块中,使用这个exception对象初始化用捕获的exception对象初始化的名字,而不是throw
的参数,即使这是一个左值。
如果你通过非const引用catch
,那么你可以改变exception对象,但不是它初始化的。 如果您重新抛出exception的方式,您可以改变程序的行为,如果您通过值或const引用( const_cast
s旁边)捕获您不能这样做。
当最后一个catch块不经过一个重新抛出(即无参数抛出expression式求值)完成时,exception对象被销毁。
exception对象仅在catch
块中可用。 您不能在catch
块之外使用exception对象。 以下步骤发生在您抛出exception并捕获时:
try { MyException anObject; throw anObject; //1 } catch(MyException exObject) { }
-
throw
子句(// 1)接收本地对象anObject
,并将其视为值参数:它创buildanObject
的副本。 -
catch
处理程序捕获一个MyException对象,它又是一个值参数。 在这一刻,创build另一个副本。 - 如果
catch
处理程序实现以便接收对象的引用(catch (MyException &o))
,则避免第二个副本。 - 如果
catch
处理程序通过const&
接收exception对象,那么你只能调用const
方法。
首先,你抛出的物体几乎立即就超出了范围。 exception处理程序将捕获什么是原始对象的副本 。 捕获处理程序执行后,该副本将被删除, 除非您通过值(而不是引用)捕获它。 在这种情况下,将会创build另一个副本。 但是你应该通过引用(最好是const的)来捕获它。