繼承與虛擬解構式 ( inherit & virtual destruct )

  • 2644
  • 0
  • c++
  • 2010-11-20

Inherit & virtual destruct

 

雖然這篇的程式碼與執行結果都樂樂長

但請耐心看完

並且想一想

會有幫助的^^

 

	#include "stdafx.h"

class Class_X
{
public:    
    Class_X()    {printf("Class_X Construct\n");}
    ~Class_X()    {printf("Class_X Destruct\n");}
};

class Class_Y
{
public:    
    Class_Y()    {printf("Class_Y Construct\n");}
    ~Class_Y()    {printf("Class_Y Destruct\n");}
};


class Class_A
{
public:    
    Class_A()    {printf("Class_A Construct\n");}
    virtual ~Class_A()    {printf("Class_A Destruct\n");}
    Class_Y mClass_Y;
};


class Class_B
{
public:    
    Class_B()    {printf("Class_B Construct\n");}
    ~Class_B()    {printf("Class_B Destruct\n");}
    Class_Y mClass_Y;
};


class Class_C : public Class_A
{
public:    
    Class_C()    {printf("Class_C Construct\n");}
    ~Class_C()    {printf("Class_C Destruct\n");}
    Class_X        mClass_X;
};


class Class_D : public Class_B
{
public:    
    Class_D()    {printf("Class_D Construct\n");}
    ~Class_D()    {printf("Class_D Destruct\n");}
    Class_X        mClass_X;
};


class Class_E : protected Class_B // 你也可以用private試試看
{
public:    
    Class_E()    {printf("Class_E Construct\n");}
    ~Class_E()    {printf("Class_E Destruct\n");}
    Class_X        mClass_X;
};


int _tmain(int argc, _TCHAR* argv[])
{
    Class_A *pClass_A = new Class_A();
    delete pClass_A;
    printf("\n");


    Class_B *pClass_B = new Class_B();
    delete pClass_B;
    printf("\n");


    Class_C *pClass_C1 = new Class_C();
    delete pClass_C1;
    printf("\n");


    Class_A *pClass_C2 = new Class_C();
    delete pClass_C2;
    printf("\n");
    
    
    Class_D *pClass_D1 = new Class_D();
    delete pClass_D1;
    printf("\n");



    // 請注意看這行的結果
    // 是否少了什麼
    Class_B *pClass_D2 = new Class_D();
    delete pClass_D2;
    printf("\n");


    Class_E *pClass_E1 = new Class_E();
    delete pClass_E1;
    printf("\n");


    // 你覺得這裡會發生什麼事
    // 有興趣的人可以自己編編看
    /*Class_B *pClass_E2 = new Class_E();
    delete pClass_E2;
    printf("\n");*/



    // 不要理我, 我只是讓程式暫停的迴圈=..=a
    char cPause;
    do
    {
        cPause = getchar();
        if(cPause == EOF) 
            break;

    } while(cPause != '\n');

    
    return 0;
}

 

 

以下是執行結果

請花點時間看一下

如果覺得這樣看很累的話

也可以把上面的程式碼抓回去自己編看看

Class_Y Construct
Class_A Construct
Class_A Destruct
Class_Y Destruct

Class_Y Construct
Class_B Construct
Class_B Destruct
Class_Y Destruct

Class_Y Construct
Class_A Construct
Class_X Construct
Class_C Construct
Class_C Destruct
Class_X Destruct
Class_A Destruct
Class_Y Destruct

Class_Y Construct
Class_A Construct
Class_X Construct
Class_C Construct
Class_C Destruct
Class_X Destruct
Class_A Destruct
Class_Y Destruct

Class_Y Construct
Class_B Construct
Class_X Construct
Class_D Construct
Class_D Destruct
Class_X Destruct
Class_B Destruct
Class_Y Destruct

Class_Y Construct
Class_B Construct
Class_X Construct
Class_D Construct
Class_B Destruct
Class_Y Destruct

Class_Y Construct
Class_B Construct
Class_X Construct
Class_E Construct
Class_E Destruct
Class_X Destruct
Class_B Destruct
Class_Y Destruct

 

由上面的結果我們可以知道

當我們使用父系的類別去接子系類別new出來的記憶體時

若沒有將解構式宣告為virtaul

在清除時會造成記憶體清除不乾淨的問題

所以在使用上要特別注意

至於為什麼c++的語言有這種缺陷(還是故意的?)

目前我在網路上並沒有看到一些比較詳盡的解釋

如果有知道的朋友也請指點我一下