C++淺析——繼承類內存分佈和虛析構函數

繼承類研究
1、 Code

1.1 Cbase, CTEST爲基類,CTest2爲其繼承類,並重新申明瞭基類中的同名變量

class CBase
{
public:
        int        Data;

        CBase();
        ~CBase();
};

class CTEST
{
        //Data:
private:
        int        PrivateData1;
        int        PrivateData2;
public:
        int        Data;
        
        //Method:
public:
        CTEST();
        ~CTEST();
        void PrintData();
};

class CTest2 : public CBase, public CTEST
{
public:
        int        Data;
        
        CTest2();
        ~CTest2();

        void PrintData2();

private:
        int        PrivateData1;
        int        PrivateData2;
};
1.2 測試代碼
分別輸出基類和繼承類的大小,但在delete對象的時候是delete基類的對象指針
 CTest2*        poCTest2 = new CTest2;
        
printf("CTest size = %d, CTest2 size = %d\n", sizeof(CTEST), sizeof(CTest2));
        
CTEST*        poCTest = poCTest2;
delete        poCTest;

2、 運行結果


3、 繼承類的大小
儘管繼承類中重新定義了和基類中同名的成員變量,但他們並不是同一份數據,而是繼承類中包含了基類的全部數據,所以繼承類的大小是自身大小加上所有父類的大小,通過VS調試跟蹤也可以清楚的看到這一點。
 

4、 如果父類的析構函數不聲明爲Virtrual的後果
從運行結果上來看,只打印出了Ctest基類的析構函數輸出,Cbase基類和繼承類的析構函數都未被調用,如果CBase基類或繼承類在析構函數中幹了其他事情,那就永遠不會執行了。同時由於poCTest的指針和poCTest2的指針不是同一個,導致delete的時候不正確(因爲new的時候系統記錄的是poCTest2的指針和大小,並未記錄poCTest的指針)


5、 如果一個類可能會被繼承,則一定要將其析構函數申明爲虛函數

將父類申明爲虛析構函數後,基類的析構函數就動態綁定爲繼承類的析構函數了,繼承類析構時就會調用父類的析構函數,從而使基類全部正確析構。

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