說起來還真是慚愧,如此簡單的問題一直就沒有太注意。今天偶爾才開始關注。
#include <iostream>
using namespace std;

class CBase


{
public:
CBase()

{
cout<<"I in Base constructor"<<endl;
}
virtual ~CBase()

{
cout<<"I in Base deconstructor"<<endl;
}
};

class CDerived : public CBase


{
public:
CDerived()

{
cout<<"I in CDerived constructor"<<endl;
}
virtual ~CDerived()

{
cout<<"I in CDerived deconstructor"<<endl;
}
};


int main()


{

CBase *pBase = new CDerived();
delete pBase;

return 0;
}
輸出結果
I in Base constructor
I in CDerived constructor
I in CDerived deconstructor
I in Base deconstructor
以前一直覺得virtual的指定是可有可無的,現在才知道,如果不制定virutal,那么I in CDerived deconstructor就不會調用。這個與construtor完全不一樣,事實上也正是這樣把他/它忽略了。
接著就要想想如何實現的呢?
先來看看構造函數
004012CF . 894D F0 mov [ebp-10], ecx
004012D2 . 8B4D F0 mov ecx, [ebp-10]
004012D5 . E8 D0FDFFFF call 004010AA ; 調用基類的構造函數
004012DA . C745 FC 00000>mov dword ptr [ebp-4], 0
004012E1 . 8B45 F0 mov eax, [ebp-10]
004012E4 . C700 3C204300 mov dword ptr [eax], offset CDerived::`vftable'
004012EA . 68 2D104000 push 0040102D
004012EF . 68 1C204300 push 0043201C ; ASCII "I in CDerived constructor"
004012F4 . 68 40954300 push offset std::cout
004012F9 . E8 CAFDFFFF call 004010C8
和以前理解的一樣,不多解釋
下面是析構函數(注意這里是CDerived生成的delete函數哦)
00401069 . /E9 32040000 jmp CDerived::`scalar deleting destructor'
004014BA |. 894D FC mov [ebp-4], ecx
004014BD |. 8B4D FC mov ecx, [ebp-4]
004014C0 |. E8 F9FBFFFF call 004010BE ; 調用子類的析構函數
004014C5 |. 8B45 08 mov eax, [ebp+8]
004014C8 |. 83E0 01 and eax, 1
004014CB |. 85C0 test eax, eax
004014CD |. 74 0C je short 004014DB
004014CF |. 8B4D FC mov ecx, [ebp-4]
004014D2 |. 51 push ecx ; /Arg1
004014D3 |. E8 A8130000 call operator delete ; \operator delete
0040153F . 894D F0 mov [ebp-10], ecx
00401542 . 8B45 F0 mov eax, [ebp-10]
00401545 . C700 3C204300 mov dword ptr [eax], offset CDerived::`vftable'
0040154B . C745 FC 00000>mov dword ptr [ebp-4], 0
00401552 . 68 2D104000 push 0040102D
00401557 . 68 80204300 push 00432080 ; ASCII "I in CDerived disconstructor"
0040155C . 68 40954300 push offset std::cout
00401561 . E8 62FBFFFF call 004010C8
00401566 . 83C4 08 add esp, 8
00401569 . 8BC8 mov ecx, eax
0040156B . E8 1CFBFFFF call 0040108C
00401570 . C745 FC FFFFF>mov dword ptr [ebp-4], -1
00401577 . 8B4D F0 mov ecx, [ebp-10]
0040157A . E8 E0FAFFFF call 0040105F ; 基類的析構函數
結論:
編譯器不能自動識別析構函數,必須要多態的標識。
posted on 2008-05-31 12:32
margin 閱讀(201)
評論(0) 編輯 收藏 引用 所屬分類:
C/C++