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++的語言有這種缺陷(還是故意的?)
目前我在網路上並沒有看到一些比較詳盡的解釋
如果有知道的朋友也請指點我一下