Effective_C++:14、總是讓base classs擁有virtual destructor

14、總是讓base classs擁有virtual destructor

1、爲啥讓base classs擁有virtual destructor

        在含有繼承關係的情況中,讓基類的析構函數爲虛函數,則在銷燬指向派生類的基類指針時,會成功調用派生類的析構函數,否則只調用基類的析構函數。
        有時,需要class跟蹤記錄他的對象數量,則可以定義一個static成員初始爲0,調用構造函數一次令其加1,調用析構函數令其減1,以此記錄對象的數量。故,定義一個類EnermyTarget來表示敵軍目標,而另一個類EnermyTank來表示敵軍坦克,繼承於EnermyTarget,他們均含有一個static成員來記錄該類對象的數量。
class EnermyTarget {
public:
    EnermyTarget() { ++numTargets; }
    EnermyTarget(const EnermyTarget&) { ++numTargets; }
    ~EnermyTarget() { --numTargets; }
    static size_t numberOfTargets() { return numTargets; }
    virtual bool destroy();
private:
    static size_t numTargets;
};
size_t EnermyTarget::numTargets;
class EnermyTank {
public:
    EnermyTank() { ++numTanks; }
    EnermyTank(const EnermyTank& rhs) : EnermyTarget(rhs) { ++numTanks; }
    ~EnermyTank() { --numTanks; }
    static size_t numberOfTanks() { return numTanks; }
    virtual bool destroy();
private:
    static size_t numTanks;
};
EnermyTarget *targetPtr = new EnermyTank;
...
delete targetPtr;

        以上,targetPtr指針爲基類指針,指向了派生類的對象,最後,delete該指針來銷燬這個對象。然而此時基類的析構函數不是虛函數,這將引起結果未定義,即產生不可預期的行爲,而最有可能的是程序未調用派生類的析構函數,則導致numTanks記錄敵軍坦克的數量有誤。

        因此,需要讓基類的析構函數爲虛函數,即可成功調用派生類和基類的析構函數。

        有時,我們可能希望構造一個抽象類,不希望被實體化,但是沒有什麼合適的函數可以聲明爲純虛函數,那麼你可以聲明一個爲純虛函數的析構函數。

2、沒有繼承關係的類的析構函數

        在含有繼承關係的情況下,讓基類的析構函數爲虛函數。若沒有繼承關係,則沒有必要定義爲虛函數,也不應該定義爲虛函數。

        首先,我們得知道,爲實現虛函數,通常是讓對象夾帶一些額外信息,即含有一個虛函數表指針,用來在執行期間協助決定使用哪個虛函數。而每個含有虛函數的類都有一個虛函數表,當對象調用虛函數時,編譯器根據對象的虛函數表指針所指的虛函數表,決定調用哪個虛函數。即編譯器在虛函數表中尋找合適的函數指針。

        我們定義一個只含有兩個short int的數據成員,且沒有虛函數的類。若short int佔16bits,則該類對象可以塞進一個32-bit的緩存器中。甚至,可以把他當作32bit的數據傳遞給其他語言撰寫的函數中。若將該類的析構函數定義爲虛函數,則該類含有一個虛函數表,該類對象都含有一個虛函數表指針,則不能將其作爲32bit的數據,也不能將其放進32-bit的緩存器中。

3、讓base classs擁有virtual destructor

        總之,當一個類作爲基類時,其大概率含有虛函數(實現多態),讓其析構函數爲虛函數。若沒有繼承關係,不包含虛函數,則不需要聲明析構函數爲虛函數。

        另外,若將一個是虛函數的析構函數聲明爲inline,以避免其調用函數的開銷。你必須明白,他是虛函數則要求將他的函數指針放進虛函數表中,而inline函數不是一個獨立的函數,要取得他的地址,則需要產生一個out-of-line函數副本。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章