2
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 被调用?即使异常被引用捕获,我相信仍然会创建一个临时的。

4

2 回答 2

1

你用的是什么编译器?

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

原始实验按预期/允许的方式工作。的参数throw被复制到内部临时文件中,该临时文件稍后用于初始化catch参数。尽管允许编译器直接使用您的原始临时文件,但相应地延长了它的生命周期。

于 2012-07-07T06:30:12.497 回答
-1

可能还有其他错误,但我现在看到的是throw(Error1(5));创建了一个临时(或rvalue)类型Error1。你想要一个lvalue,这意味着你应该这样做throw(*new Error1(5));(我相信这会造成内存泄漏,但我可能是错的),或者你可以创建一个全局Error1对象并抛出它。

PS:throw(*new Error1(5));如果有人想发表评论,我很想知道是否会造成内存泄漏。会catch破坏它捕获的物体吗?如果是这样,我认为您只需Error1在需要时创建新的 s 就可以了。

于 2012-07-07T06:53:48.527 回答