C++ 引用捕获异常时未创建临时对象?

C++ 引用捕获异常时未创建临时对象?,c++,visual-c++,exception,exception-handling,C++,Visual C++,Exception,Exception Handling,此输出指示为catch处理程序复制构造了Error1对象。因为没有为Error1对象定义复制构造函数,所以使用了默认的复制构造函数 当我取消注释用于定义副本构造函数的注释部分时,我得到以下输出 Inside fun CTOR Error1 DTOR Error1 Error1 type occured with code:5 DTOR Error1 为什么只有一个DTOR被调用?即使引用捕获到异常,我相信仍然会创建一个临时异常。您使用的编译器是什么 当您使用Error1&obj参数引入

此输出指示为catch处理程序复制构造了Error1对象。因为没有为Error1对象定义复制构造函数,所以使用了默认的复制构造函数

当我取消注释用于定义副本构造函数的注释部分时,我得到以下输出

Inside fun

CTOR Error1

DTOR Error1

Error1 type occured with code:5

DTOR Error1

为什么只有一个DTOR被调用?即使引用捕获到异常,我相信仍然会创建一个临时异常。

您使用的编译器是什么

当您使用Error1&obj参数引入(即取消对您的copy构造函数版本的注释)时,代码被认为是无效的。throw应该能够创建其参数的副本,而copy构造函数的版本禁止复制临时变量。代码格式不正确。如果您的编译器接受它,可能是因为它非法允许将非常量引用绑定到临时变量,我怀疑它是启用了扩展的MSVC++编译器


最初的实验按其设想/允许的方式进行。throw的参数被复制到一个内部临时变量,该临时变量稍后用于初始化catch参数。尽管允许编译器直接使用原始临时文件,但会相应地延长其生存期。

您使用的编译器是什么

当您使用Error1&obj参数引入(即取消对您的copy构造函数版本的注释)时,代码被认为是无效的。throw应该能够创建其参数的副本,而copy构造函数的版本禁止复制临时变量。代码格式不正确。如果您的编译器接受它,可能是因为它非法允许将非常量引用绑定到临时变量,我怀疑它是启用了扩展的MSVC++编译器


最初的实验按其设想/允许的方式进行。throw的参数被复制到一个内部临时变量,该临时变量稍后用于初始化catch参数。虽然编译器可以直接使用您的原始临时文件,并相应地延长其生存期。

可能还有其他错误,但我现在看到的是throwError15;创建Error1类型的临时值或右值。你想要一个左值,这意味着你要么抛出*newerror15;我相信这会造成内存泄漏,但我可能错了,或者你可以创建一个全局Error1对象并抛出它


附言:我想知道是否抛出*新错误15;如果有人想评论,会造成内存泄漏。捕获会破坏它捕获的对象吗?如果是这样的话,我想你可以随时创建新的错误。可能还有其他错误,但我现在看到的是投掷者15;创建Error1类型的临时值或右值。你想要一个左值,这意味着你要么抛出*newerror15;我相信这会造成内存泄漏,但我可能错了,或者你可以创建一个全局Error1对象并抛出它


附言:我想知道是否抛出*新错误15;如果有人想评论,会造成内存泄漏。捕获会破坏它捕获的对象吗?如果是这样的话,我认为您可以随时创建新的Error1。

看起来输出取决于编译器和异常运行时实现。例如,GCC4.3.4没有使用默认的复制构造函数为您的第一个代码示例生成任何临时值。您可以在这里看到一个示例:首先,如果您将DTOR定义为虚拟的,您将得到第一个行为等于第二个行为。@klement:这里没有多态行为,因此我相信使用虚拟DTOR是正确的unecessary@Jason当前位置我安排了一个实验,而且我在VS2010-virtual中得到的结果使两个代码部分的工作方式相同。@klement:在gcc中,我得到相同的结果,而没有添加虚拟。。。因此,使用虚拟关键字可能是VS2010特有的奇特,但对于这个特定场景,一般来说,C++语言不需要。看起来输出依赖于编译器和异常运行时实现。例如,GCC4.3.4没有使用默认的复制构造函数为您的第一个代码示例生成任何临时值。您可以在这里看到一个示例:首先,如果您将DTOR定义为虚拟的,您将得到第一个行为等于第二个行为。@klement:这里没有多态行为,因此我相信使用虚拟DTOR是正确的unecessary@Jason当前位置我安排了一个实验,而且我在VS2010-virtual中得到的结果使两个代码部分的工作方式相同。@klement:在gcc中,我得到相同的结果,而没有添加虚拟。。。因此,使用虚拟关键字可能是VS2010特有的奇特,但一般来说,对于特定的场景,C++语言不必要。如果他将其定义为私有,则无效。他仍然可以依赖默认的复制CTOR。@klement:OP中的用户定义的CTOR采用非常量引用
类型,这意味着它不能接受一个临时变量作为参数…@klement:首先,声明任何副本构造函数都会禁用编译器提供的构造函数,这可能就是您所说的默认值。其次,只要引用参数为非常量,即使使用公共副本构造函数,代码也是无效的。正如我已经说过的,这样的复制构造函数不能用于复制临时值。对不起,不知何故误读了你们的答案。我想你是说,如果我们注释掉了复制CTOR代码,那么复制CTOR代码就无效了。@rocky:请注意,throw/catch已经有了一些功能,可以绕过语言的限制。例如,您可以执行throw 5和catch int&。也就是说,它允许您将非常量引用绑定到临时引用。这已经是一个相当了不起的壮举,在语言的其他任何地方都是被禁止的。即使源对象是常量,执行临时消除也可能是合法的。。。但我不确定。如果他把它定义为私人,它就无效了。他仍然可以依赖默认的复制构造函数。@klement:OP中的用户定义的构造函数采用非常量引用类型,这意味着它不能接受临时变量作为参数…@klement:首先,声明任何复制构造函数都会禁用编译器提供的构造函数,这可能就是您所说的默认构造函数。其次,只要引用参数为非常量,即使使用公共副本构造函数,代码也是无效的。正如我已经说过的,这样的复制构造函数不能用于复制临时值。对不起,不知何故误读了你们的答案。我想你是说,如果我们注释掉了复制CTOR代码,那么复制CTOR代码就无效了。@rocky:请注意,throw/catch已经有了一些功能,可以绕过语言的限制。例如,您可以执行throw 5和catch int&。也就是说,它允许您将非常量引用绑定到临时引用。这已经是一个相当了不起的壮举,在语言的其他任何地方都是被禁止的。即使源对象是常量,执行临时消除也可能是合法的。。。但我不确定。你的渔获量是什么样的?您正在抛出取消引用的指针,对吗?因此,如果你的捕获像catchError1 obj或catchError1&obj,它将导致内存泄漏。如果你手动删除你的错误1,它还会泄漏内存吗?我相信你不能手动删除,除非你按指针抛出并按指针捕获。我不知道你可以这样做。我以后再试试,谢谢。这不是个好主意。。。如果您编写其他人将使用的代码抛出这样的动态分配对象,按照惯例,他们很可能会编写采用l值引用的catch语句,您将100%保证有泄漏的代码。异常运行时是为了处理临时异常对象而创建的,所以请按照设计的方式使用系统,不要试图将它和使用您的代码的任何其他人排除在外。您的捕获是什么样的?您正在抛出取消引用的指针,对吗?因此,如果你的捕获像catchError1 obj或catchError1&obj,它将导致内存泄漏。如果你手动删除你的错误1,它还会泄漏内存吗?我相信你不能手动删除,除非你按指针抛出并按指针捕获。我不知道你可以这样做。我以后再试试,谢谢。这不是个好主意。。。如果您编写其他人将使用的代码抛出这样的动态分配对象,按照惯例,他们很可能会编写采用l值引用的catch语句,您将100%保证有泄漏的代码。异常运行时是为了处理临时异常对象而创建的,因此请按照设计的方式使用系统,不要试图将它和使用您的代码的任何其他人排除在外。
Inside fun

CTOR Error1

DTOR Error1

Error1 type occured with code:5

DTOR Error1
Inside fun

CTOR Error1

Error1 type occured with code:5

DTOR Error1