构造函数应该尽量避免产生异常



构造函数应该尽量避免产生异常

1.说明

       构造函数是对一个对象进行初始化,一般来说,构造函数不应该设计的太复杂,即只进行简单的成员变量的初始化即可,
这样就可以更好的保证构造函数不会产生异常。



2.构造函数产生异常的危害

    C++在进行实例化对象,当调用构造函数的过程中发生异常时,这将导致无法调用对象的析构函数,
    这时仅仅清理和释放产生异常前的那些C++管理的变量空间等,而我们动态申请的资源(通过析构函数释放)是无法自动释放的,这将会导致资源泄露。


3.解决构造函数出现的异常

如果你的构造函数,不仅仅是进行简单的成员变量的初始化,还需涉及到了一系列资源的分配,可以通过下述方法解决:

容易出现资源泄露代码如下:

class Test
{
public:
    Test()
    {

/*
 pA = new A(), 注意了,这里针对的是动态分配资源,失败返回NULL,进行DELETE NULL不会出现异常,如果是其他资源,这里出现异常需要额外的处理,
  即需要考虑资源失败和成功的不同处理方式,例如,对互斥器未加锁的情况下进行解锁,会导致未定义行为。

*/
        pA = new A();     
        ...         
    }


    ~Test()
    {
        
        delete pA;
...
    }
private:
    A* pA;
};






(1)、方法一:通过异常处理机制,一旦发生异常,先进行资源的释放

Test::Test()
{
  
         try
        {
            pA = new A();     //资源的异常,资源申请失败也就谈不上释放资源了,更主要考虑的是,申请资源成功后的下面的异常。
            ...
        }
        catch (...)
        {
            if(NULL != pA)
            {
                  delete pA;
            }
            throw;  //抛出对应异常,交给上层处理
        }
   
}





(2)、方法二:通过智能指针进行管理

class Test
{
public:
    Test()
    {
        spA = std::make_shared<A>;  //资源由智能指针进行处理
        ...
    }
    ~Test()
    {
        
    }
private:
    std::shared_ptr< A > spA;
};




 

(3)、方法三:把资源申请和释放的操作存放在另外的Init()和Release()函数


class Test
{
public:
    Test()
    {
        pA = NULL;
        if (!Init())
{
                  Release();
}
...
    }
    ~Test()
    {
        Release();
    }
 
private:
    bool Init()
    {
        
        
            try
            {
         pA = new A();   //资源的异常,资源申请失败也就谈不上释放资源了,更主要考虑的是,申请资源成功后的下面的异常。
                  ...
            }
            catch (...)
            {
                return false;
            }
        }
        return true;
    }
 
    void Release()
    {
        if(NULL != pA)
        {
            delete pA;
            pA = NULL;
       }
    }
private:
    A* pA;
    
};






总结:

(1)、构造函数中发生异常,会导致析构函数不能被调用,但对象本身已申请到的内存资源会被系统释放(已申请到资源的内部成员变量会被系统依次逆序调用其析构函数)。
(2)、由于析构函数不能被调用,这就可能会造成内存泄露或系统资源未被释放。

(3)、构造函数中如果发生异常,必须在构造函数抛出异常之前,把系统资源释放掉,以防止内存泄露。




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值