2012-07-07 52 views
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(); 

} 

OUTPUT:通过引用捕获异常时临时对象不会创建?

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

+0

看起来输出依赖于编译器和异常运行时实现。例如,gcc 4.3.4不会为您的第一个代码示例使用默认的复制构造函数生成任何临时对象。你可以在这里看到一个例子:http://ideone.com/9QyLf – Jason 2012-07-07 06:26:59

+0

首先,如果你定义你的DTOR为虚拟的,你将得到与第二个相同的第一个行为。 – klement 2012-07-07 06:28:15

+0

@klement:这里没有多态行为发生,所以我相信使用'virtual' DTOR是不必要的 – Jason 2012-07-07 06:29:30

回答

1

你使用什么编译器?

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

原始实验按照设想/允许的方式工作。 throw的参数被复制到一个内部临时参数,后者用于初始化参数catch。尽管编译器可以直接使用原始临时文件,但相应地延长了其使用期限。

+1

如果他将其定义为私人,则它变为无效。他仍然可以依靠默认拷贝CTOR。 – klement 2012-07-07 06:31:33

+0

@klement:来自OP的用户定义的CTOR采用非''contst'参考类型,这意味着它不能接受作为参数的临时... – Jason 2012-07-07 06:32:24

+0

@klement:首先,声明任何复制构造函数禁用编译器 - 提供了一个(这可能是你所谓的“默认”)。其次,只要引用参数是非const的,即使使用公共拷贝构造函数,代码也是无效的。正如我已经说过的,这种复制构造函数不能用于复制临时对象。 – AnT 2012-07-07 06:34:14

-1

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

PS:我很想知道如果有人想评论,throw(*new Error1(5));确实会造成内存泄漏。 catch破坏它捕获的对象吗?如果是这样,我认为你应该没问题,只要你需要创建新的Error1即可。

+0

你会发现什么?你正在抛弃解除引用的指针吗?所以如果你的catch类似catch(Error1 obj)或catch(Error1&obj)它会导致内存泄漏。 – hackrock 2012-07-07 07:02:32

+0

如果你手动删除了'Error1',它会不会泄漏内存? – anthropomorphic 2012-07-07 07:04:28

+0

我相信你不能做手动删除,除非你抛出指针,并通过指针捕获 – hackrock 2012-07-07 07:07:03