C++程序中抛出异常后对象的析构顺序


转自:http://blog.sina.com.cn/s/blog_86cee8660100vj49.html

throw的时候将被抛出的对象拷贝一份到专用的异常栈上,接着按声明时相反的顺序先析构掉本层作用域内的对象,再往上析构掉高层作用域中的对象,依次上推直到将throw之前的,在本函数中声明的所有对象都析构掉为止。然后再执行catch中的相关语句,最后才析构掉拷贝对象。

下面的代码用来说明对象析构顺序:


 

#include <Windows.h>


#include <exception>

#include <string>

using namespace std;


class TException : public std::exception {

public:

TException() 

{

OutputDebugStringA("TException construct\n");

}


TException( const TException &te )

{

this->message_ = te.message_;

}

TException(const std::string& message) :

message_(message) {}


virtual ~TException() throw() 

{

OutputDebugStringA("TException destruct\n");

}


virtual const char* what() const throw() 

{

if ( message_.empty() )

{

return "Default TException.";

}

else

{

return message_.c_str();

}

}


protected:

std::string message_;


};


int main( void )

{

try

{

TException te;


throw te;

}

catch ( TException &te )

{

OutputDebugStringA( te.what() );

OutputDebugStringA( "\n");

}


return 0;

}


 输出结果:

 

TException construct

TException destruct

Default TException.

TException destruct


所以在c++这种异常机制下异常对象会做两次析构操作,当catch参数不是引用而是值传递时(例:catch ( TException te ) ),这种情况的异常对象要做三次析构操作, 这往往程序员会忘记考虑这种情况导致未知情况发生。

所以,更好一点的c++异常机制是将异常对象分配在堆中,在catch语句中delete。


例子代码如下:

 

#include <Windows.h>


#include <exception>

#include <string>

using namespace std;


class TException : public std::exception {

public:

TException() 

{

OutputDebugStringA("TException construct\n");

}


TException( const TException &te )

{

this->message_ = te.message_;

}

TException(const std::string& message) :

message_(message) {}


virtual ~TException() throw() 

{

OutputDebugStringA("TException destruct\n");

}


virtual const char* what() const throw() 

{

if ( message_.empty() )

{

return "Default TException.";

}

else

{

return message_.c_str();

}

}


protected:

std::string message_;


};


int main( void )

{

try

{

throw new TException();

}

catch ( TException *pe )

{

OutputDebugStringA( pe->what() );

OutputDebugStringA( "\n");


delete pe;

}


return 0;

}


 

输出结果:

 

TException construct

Default TException.

TException destruct

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值