class Error1
{
public:
int errorcode;
Error1(int x):errorcode(x){ cout<<"CTOR Error1"<<endl; }
//Error1(Error1& obj ){
// errorcode = obj.errorcode;
// cout<<"CopyCTOR Error1"<<endl;
//}
~Error1(){cout<<"DTOR Error1"<<endl; }
};
void fun()
{
cout<<"Inside fun"<<endl;
throw(Error1(5));
}
int main()
{
try{
fun();
}
catch(Error1& eobj)
{
cout<<"Error1 type occured with code:"<<eobj.errorcode<<endl;
}
cin.get();
}
输出:
Inside fun
CTOR Error1
DTOR Error1
Error1 type occured with code:5
DTOR Error1
此输出指示 Error1 对象是为 catch 处理程序构造的复制。由于未为 Error1 对象定义复制构造函数,因此使用默认复制构造函数。
当我取消注释用于定义复制构造函数的注释部分时,我得到以下输出。
Inside fun
CTOR Error1
Error1 type occured with code:5
DTOR Error1
为什么只调用一个 DTOR?即使通过引用捕获异常,我相信仍然会创建一个临时的。
你用的是什么编译器?
当您使用Error1& obj
参数引入(即取消注释)您的复制构造函数版本时,代码应该变得无效。 throw
应该能够创建其参数的副本,而您的复制构造函数版本禁用临时副本。代码格式不正确。如果您的编译器接受它,则可能是因为它非法允许将非常量引用绑定到临时引用(我怀疑它是启用了扩展的 MSVC++ 编译器)。
原始实验按预期/允许的方式工作。throw
的参数被复制到内部临时,稍后用于初始化catch
参数。尽管允许编译器直接使用原始临时,但相应地延长了其生存期。
可能还有其他错误,但我现在看到的是throw(Error1(5));
创建了一个 Error1
类型的临时(或rvalue
)。你想要一个lvalue
,这意味着你应该做throw(*new Error1(5));
(我相信这会造成内存泄漏,但我可能是错的),或者你可以创建一个全局Error1
对象并抛出它。
PS:我很想知道throw(*new Error1(5));
是否确实造成了内存泄漏,如果有人想发表评论。catch
会破坏它捕获的物体吗?如果是这样,我认为您应该可以在需要时创建新Error1
。