虛析構函式
析構函式的工作方式是:最底層的派生類(most derived class)的析構函式最先被呼叫,然後呼叫每乙個基類的析構函式。
因為在c++中,當乙個派生類物件通過使用乙個基類指標刪除,而這個基類有乙個非虛的析構函式,則結果是未定義的。執行時比較有代表性的後果是物件的派生部分不會被銷毀。然而,基類部分很可能已被銷毀,這就導致了乙個古怪的「部分析構」物件,這是乙個洩漏資源。排除這個問題非常簡單:給基類乙個虛析構函式。於是,刪除乙個派生類物件的時候就有了你所期望的正確行為。將銷毀整個物件,包括全部的派生類部分。
但是,一般如果不做基類的類的析構函式一般不宣告為虛函式,因為虛函式的實現要求物件攜帶額外的資訊,這些資訊用於在執行時確定該物件應該呼叫哪乙個虛函式。典型情況下,這一資訊具有一種被稱為 vptr(virtual table pointer,虛函式表指標)的指標的形式。vptr 指向乙個被稱為 vtbl(virtual table,虛函式表)的函式指標陣列,每乙個包含虛函式的類都關聯到 vtbl。當乙個物件呼叫了虛函式,實際的被呼叫函式通過下面的步驟確定:找到物件的 vptr 指向的 vtbl,然後在 vtbl 中尋找合適的函式指標。這樣子會使類所占用的記憶體增加。
定義純虛析構函式(pure virtual destructor)
純虛成員函式通常沒有定義;它們是在抽象類中宣告,然後在派生類中實現。比如說下面的例子:
class file //an abstract class
;
但是,在某些情況下,我們卻需要定義乙個純虛成員函式,而不僅僅是宣告它。最常見的例子是純虛析構函式。在宣告純虛析構函式時,不要忘了同時還要定義它。
class file //abstract class
;
file::~file() {} //definition of dtor
為什麼說定義純虛析構函式是非常重要的
派生類的析構函式會自動呼叫其基類的析構函式。這個過程是遞迴的,最終,抽象類的純虛析構函式也會被呼叫。
如果純虛析構函式只被宣告而沒有定義,那麼就會造成執行時(runtime)崩潰。(在很多情況下,這個錯誤會出現在編譯期,但誰也不擔保一定會是這樣。)純虛析構函式的啞元實現(dummy implementation,即空實現)能夠保證這樣的**的安全性。
class diskfile : public file
;
file * pf = new diskfile;
//. . .
delete pf; //ok, ultimately invokes file::~file()
在某些情況下定義其它純虛成員函式可能也是非常有用的(比如說在除錯應用程式以及記錄應用程式的日誌時)。例如,在乙個不應該被呼叫,但是由於乙個缺陷而被呼叫的基類中,如果有乙個純虛成員函式,那麼我們可以為它提供乙個定義。
class abstract
;
int abstract::func()
{
std::cerr<<"got called from thread " << thread_id<<
"at: "《這樣,我們就可以記錄所有對純虛函式的呼叫,並且還可以定位錯誤**;不為純虛函式提供定義將會導致整個程式無條件地終止。
C 虛析構函式 純虛析構函式
虛析構函式 析構函式的工作方式是 最底層的派生類 most derived class 的析構函式最先被呼叫,然後呼叫每乙個基類的析構函式。因為在c 中,當乙個派生類物件通過使用乙個基類指標刪除,而這個基類有乙個非虛的析構函式,則結果是未定義的。執行時比較有代表性的後果是物件的派生部分不會被銷毀。然...
C 虛析構函式 純虛析構函式
虛析構函式 析構函式的工作方式是 最底層的派生類 most derived class 的析構函式最先被呼叫,然後呼叫每乙個基類的析構函式。因為在c 中,當乙個派生類物件通過使用乙個基類指標刪除,而這個基類有乙個非虛的析構函式,則結果是未定義的。執行時比較有代表性的後果是物件的派生部分不會被銷毀。然...
C 虛函式,純虛函式,虛析構和純虛析構
c 虛函式 定義為虛函式是為了允許用基類的指標來呼叫子類的這個函式,是需要具體實現的 virtual void funtion1 c 純虛函式 一 定義 純虛函式是在基類中宣告的虛函式,它在基類中沒有定義,但要求任何派生類都要定義自己的實現方法。在基類中實現純虛函式的方法是在函式原型後加 0 vir...