為什么析構(gòu)函數(shù)總是虛函數(shù)?如果這是必要的,那么為什么C++不把虛析構(gòu)函數(shù)直接作為默認(rèn)值?為什么純虛析構(gòu)函數(shù)可以通過(guò)編譯,但是不能通過(guò)連接?
回答:
編譯器總是根據(jù)類(lèi)型來(lái)調(diào)用類(lèi)成員函數(shù)。但是一個(gè)派生類(lèi)的指針可以安全地轉(zhuǎn)化為一個(gè)基類(lèi)的指針。這樣刪除一個(gè)基類(lèi)的指針的時(shí)候,C++不管這個(gè)指針指向一個(gè)基類(lèi)對(duì)象還是一個(gè)派生類(lèi)的對(duì)象,調(diào)用的都是基類(lèi)的析構(gòu)函數(shù)而不是派生類(lèi)的。如果你依賴(lài)于派生類(lèi)的析構(gòu)函數(shù)的代碼來(lái)釋放資源,而沒(méi)有重載析構(gòu)函數(shù),那么會(huì)有資源泄漏。
所以建議的方式是將析構(gòu)函數(shù)聲明為虛函數(shù)。如果你使用MFC,并且以CObject或其派生類(lèi)為基類(lèi),那么MFC已經(jīng)為你做了這件事情;CObject的析構(gòu)函數(shù)是虛函數(shù)。一個(gè)函數(shù)一旦聲明為虛函數(shù),那么不管你是否加上virtual 修飾符,它在所有派生類(lèi)中都成為虛函數(shù)。但是由于理解明確起見(jiàn),建議的方式還是加上virtual 修飾符。
C++不把虛析構(gòu)函數(shù)直接作為默認(rèn)值的原因是虛函數(shù)表的開(kāi)銷(xiāo)以及和C語(yǔ)言的類(lèi)型的兼容性。有虛函數(shù)的對(duì)象總是在開(kāi)始的位置包含一個(gè)隱含的虛函數(shù)表指針成員。如果是對(duì)于MFC類(lèi)CPoint和CSize這樣的小型類(lèi),增加一個(gè)指針就增加了很多內(nèi)存占用,而且使得其內(nèi)存表示和基類(lèi)POINT和SIZE不一致。如果兩個(gè)類(lèi)的內(nèi)存表示一致,那么這樣你可以安全地把一個(gè)類(lèi)的指針或數(shù)組當(dāng)作另一個(gè)類(lèi)的指針或數(shù)組使用。
本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶(hù)發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)
點(diǎn)擊舉報(bào)。