在《
工作中發(fā)現(xiàn)的 》中,提到析構(gòu)函數(shù)可以自己調(diào)用,并用一個(gè)例子編譯、運(yùn)行證明了。
現(xiàn)在有個(gè)問題,除了知道“析構(gòu)函數(shù)
可以自己調(diào)用”外,那么什么時(shí)候
必須顯式調(diào)用析構(gòu)函數(shù)?
先看一段現(xiàn)實(shí)生活中的代碼吧,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;
}
在上面的代碼中,就有顯式調(diào)用CString的析構(gòu)函數(shù)的代碼。cool。
因?yàn)檫€調(diào)用了
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;
//簡化后的代碼,實(shí)際運(yùn)行肯定有問題,但是關(guān)鍵東西出來了
free(pSBP);//注意這里調(diào)用的是free
pSBP = calloc(nElements, cbElement);
// construct new elements
pSBP = _GetPanePtr(0); //根據(jù)mfc的代碼,可以理解這里的pSBP和前面的pSBP還是同一個(gè)地址
for (i = 0; i < m_nCount; i++)
{
memcpy(&pSBP->strText, &afxEmptyString, sizeof(CString));
++pSBP;
}
return TRUE;
}
這個(gè)時(shí)候,如果注意到我特別注釋的free函數(shù)調(diào)用,可能已經(jīng)意識(shí)到了為什么要顯式調(diào)用析構(gòu)函數(shù)了。
如果還沒有,那么可以問自己一個(gè)面試常規(guī)問題:delete和free有什么區(qū)別?答:delete會(huì)使析構(gòu)函數(shù)被調(diào)用。
或者反過來說,
free沒有調(diào)用析構(gòu)函數(shù),那么怎么辦?所以你必須自己顯示調(diào)用析構(gòu)函數(shù)。

上面的這個(gè)例子可以這樣抽象下,現(xiàn)在需要free掉一塊內(nèi)存,而那塊內(nèi)存中,還有一個(gè)類,類里面還有指針,(這里是CString)需要在析構(gòu)函數(shù)中釋放內(nèi)存。因?yàn)橛玫氖莊ree,所以那個(gè)類的析構(gòu)函數(shù)不會(huì)自動(dòng)被調(diào)用,這個(gè)時(shí)候,就
必須顯式調(diào)用那個(gè)類的析構(gòu)函數(shù)。
這個(gè)是不是很偏的問題呢?遇到了就看看,沒有遇到過,也不會(huì)影響日常工作,哈。
另外繼續(xù)問個(gè)面試問題,new和calloc的區(qū)別?哈,構(gòu)造的函數(shù)的調(diào)用啊
所以,上面的代碼用的calloc,就必須顯示調(diào)用構(gòu)造函數(shù)啊,在哪里呢?就是
memcpy(&pSBP->strText, &afxEmptyString, sizeof(CString));
和CString的構(gòu)造函數(shù)比較下:
_AFX_INLINE CString::CString()
{ m_pchData = afxEmptyString.m_pchData; }
但是,為什么不就直接調(diào)用構(gòu)造函數(shù)呢?我也不知道。詳見下面的評(píng)論。(糾正了我的一個(gè)錯(cuò)誤)
不過,下面的代碼
CString aStr;
CString* pStr = &aStr ;
pStr->CString();
是編譯不過的。
