虛析構函式 純虛析構函式 理解

2021-05-22 03:07:45 字數 1532 閱讀 7895

虛析構函式

析構函式的工作方式是:最底層的派生類(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 虛析構函式 純虛析構函式

虛析構函式 析構函式的工作方式是 最底層的派生類 most derived class 的析構函式最先被呼叫,然後呼叫每乙個基類的析構函式。因為在c 中,當乙個派生類物件通過使用乙個基類指標刪除,而這個基類有乙個非虛的析構函式,則結果是未定義的。執行時比較有代表性的後果是物件的派生部分不會被銷毀。然...