构造函数没有返回值,无法判断构造对象成功与否,通过“抛出异常”解决。
class CObject{
public:
CObject(){
m_pSubObject = new CSubObject();
......// (1)
}
~CObject(){
.......//do other things
delete m_pSubObject ;
}
private :
CSubObject* m_pSubObject ;
};
如果在代码(1)处发生了异常,则不会调用析构函数,就会造成内存泄露。
=============================================================
解决的方式一(常规):
如果在C++的构造函数里动态创建了其他东西,就必须考虑构造函数发生异常的情况。
在C++构造函数中,正确的异常处理方法应该是:发生异常时先将已经创建的东西释放掉,然后再抛出异常给上层调用处理。
CObject::
CObject
(){
m_pSubObject = new CSubObject();
try{
......// (1)
}
catch(...){
delete m_pSubObject ; //清理对象
throw ; //抛出异常,交给上层调用
}
};
=============================================================
解决的方式二:智能指针
=============================================================
解决的方式三(非常规):在类中增加Init()函数和Release()函数,负责资源的分配与清理。
基本过程:在构造函数中调用Init()函数完成对象创建,并通过函数返回值判断对象的构建是否成功;如果失败,则调用释放函数Release();using namespace std;
class CObject{
public :
CObject(){
m_pSubObject = NULL;
if(!Init()){
Release();
}
};
~CObject(){
Release();
}
bool Init(){
try{
m_pSubObject = new CSubObject();
...//other data's initiations
}catch(...){
return false;
}
return ture;
}
void Release(){
if(m_pSubObject == NULL) return ;
delete m_pSubObject;
m_pSubObject = NULL;
}
private :
CSubObject* m_pSubObject;
...//other member data
};
Note:核心思想就是通过类的设计来避免在构造函数中抛出异常,进而避免由于构造函数随机抛出的异常,造成对象的部分构建,而不能自动调用析构函数,最终引发内存得不到及时释放而造成的内存泄露问题。