什么时候必须显式调用析构函数?

什么时候必须显式调用析构函数?
在《 工作中发现的 》中,提到析构函数可以自己调用,并用一个例子编译、运行证明了。
现在有个问题,除了知道“析构函数 可以自己调用”外,那么什么时候 必须显式调用析构函数?

先看一段现实生活中的代码吧,mfc源码中:
BOOL CStatusBar::AllocElements( int  nElements,  int  cbElement)
{
    
//  destruct old elements
    AFX_STATUSPANE *  pSBP  =  _GetPanePtr( 0 );
    
for  ( int  i  =   0 ; i  <  m_nCount; i ++ )
    {
        pSBP
-> strText. ~ CString();   //注意看这里
        
++ pSBP;
    }

    
//  allocate new elements
     if  ( ! CControlBar::AllocElements(nElements, cbElement))
        
return  FALSE;

    
//  construct new elements
    pSBP  =  _GetPanePtr( 0 );
    
for  (i  =   0 ; i  <  m_nCount; i ++ )
    {
        memcpy(
& pSBP -> strText,  & afxEmptyString,  sizeof (CString));
        
++ pSBP;
    }
    
return  TRUE;
}
在上面的代码中,就有显式调用CString的析构函数的代码。cool。
因为还调用了 CControlBar::AllocElements(),上面的代码不是很明显,我把CControlBar::AllocElements简化一下后:
BOOL CStatusBar::AllocElements( int  nElements,  int  cbElement)
{
    
//  destruct old elements
    AFX_STATUSPANE *  pSBP  =  _GetPanePtr( 0 );
    
for  ( int  i  =   0 ; i  <  m_nCount; i ++ )
    {
        pSBP
-> strText. ~ CString();    // 注意看这里
         ++ pSBP;
    }

    
//  allocate new elements
    
// if (!CControlBar::AllocElements(nElements, cbElement))
    
//     return FALSE;
    
// 简化后的代码,实际运行肯定有问题,但是关键东西出来了
    free(pSBP); // 注意这里调用的是free
    pSBP  =  calloc(nElements, cbElement);

    
//  construct new elements
    pSBP  =  _GetPanePtr( 0 );  // 根据mfc的代码,可以理解这里的pSBP和前面的pSBP还是同一个地址
     for  (i  =   0 ; i  <  m_nCount; i ++ )
    {
        memcpy(
& pSBP -> strText,  & afxEmptyString,  sizeof (CString));
        
++ pSBP;
    }
    
return  TRUE;
}
这个时候,如果注意到我特别注释的free函数调用,可能已经意识到了为什么要显式调用析构函数了。
如果还没有,那么可以问自己一个面试常规问题:delete和free有什么区别?答:delete会使析构函数被调用。
或者反过来说, free没有调用析构函数,那么怎么办?所以你必须自己显示调用析构函数

上面的这个例子可以这样抽象下,现在需要free掉一块内存,而那块内存中,还有一个类,类里面还有指针,(这里是CString)需要在析构函数中释放内存。因为用的是free,所以那个类的析构函数不会自动被调用,这个时候,就 必须显式调用那个类的析构函数。

这个是不是很偏的问题呢?遇到了就看看,没有遇到过,也不会影响日常工作,哈。

另外继续问个面试问题,new和calloc的区别?哈,构造的函数的调用啊
所以,上面的代码用的calloc,就必须显示调用构造函数啊,在哪里呢?就是
memcpy( & pSBP -> strText,  & afxEmptyString,  sizeof (CString));
和CString的构造函数比较下:
_AFX_INLINE CString::CString()
    { m_pchData 
=  afxEmptyString.m_pchData; }
但是,为什么不就直接调用构造函数呢?我也不知道。详见 dhong下面的评论。( dhong纠正了我的一个错误)

不过,下面的代码
        CString aStr;
        CString
*  pStr  =   & aStr ;
        pStr
-> CString();

是编译不过的。

 

你可能感兴趣的:(什么时候必须显式调用析构函数?)