author:zfive5(zhaozidong)
email:[email protected]
最近同住的朋友忙著找工作,他c++的問題看了一堆,我也受其影響複習了一些c++知識, virtual析構聽他說「點播率還挺高的」,所以拿來仔細研究,求個深解!
首先,定義3個類,注意了析構函式的virtual
說明class
zf5_1
virtual~
zf5_1
()};
class
zf5_2
:public
zf5_1
;virtual~
zf5_2();
};class
zf5_3
:public
zf5_2
;virtual~
zf5_3();
};然後執行**:
zf5_1*p5
=new
zf5_3
;deletep5;
1.如果都有virtual
輸出:hello zf5_3
hello zf5_2
hello zf5_1
2.如果都去掉virtual
輸出:hello zf5_1
3.如果只去掉zf5_2的virtual
輸出:hello zf5_3
hello zf5_2
hello zf5_1
第一種情況
雖然delete是基類指標,但由於有virtual析構宣告,所以delete呼叫的派生類的析構(派生類用自己的析構函式指標重寫虛函式表),然後派生類析構完成後再呼叫直接基類析構(c++就是這樣規定的,編譯器隱含這個過程,通過看彙編**,一切機理ok),這樣一級級的呼叫,就出現了第一種輸出!
第二種情況
由於沒有virtual修飾,所以delete呼叫是預設的zf5_1析構,出現第二種輸出就理所當然了。
第三種情況
由於zf5_1用virtual修飾,所以以後所有它的派生類用自己的析構函式指標重寫虛函式表裡的對應的位置,以至出現與第一種情況相同的結果!
有一種情況沒有表達,就是如果定義如下:
virtual zf5_1
zf5_2
zf5_3
zf5_4
zf5_2 *p1=new z5_4;
delete p1;
輸出:hello zf5_4
hello zf5_3
hello zf5_2
這種情況在vc6下,只要有基類virtual聲名,以後的派生類都自動加上virtual,不知道gcc和cb是怎樣處理這種情況的!有機會驗證一下,對了很有可能是c++標準規定,看來還得先去翻翻c++ primer了。
附
zf5_3
析構完成後預設呼叫zf5_2
析構彙編**:(vc6環境下)
52: ~zf5_3()
53: ;
00401413 mov ecx,dword ptr [ebp-4]
00401416 call @ilt+145(zf5_2::~zf5_2) (00401096)
0040141b pop edi
0040141c pop esi
0040141d pop ebx
0040141e add esp,44h
00401421 cmp ebp,esp
00401423 call __chkesp (00401e00)
00401428 mov esp,ebp
0040142a pop ebp
0040142b ret
思考virtual析構
author zfive5 zhaozidong email zfive5 yahoo.com.cn 最近同住的朋友忙著找工作,他 c 的問題看了一堆,我也受其影響複習了一些 c 知識 virtual 析構聽他說 點播率還挺高的 所以拿來仔細研究,求個深解!首先,定義 3個類,注意了析構函式的 vi...
virtual析構函式
當派生類物件撤銷時,一般先呼叫派生類的析構函式,然後再呼叫基類的析構函式。include using namespace std class base class derived public base int main void 執行結果 呼叫基類base的析構函式 如果在主函式中用new運算子建...
析構函式virtual與非virtual區別
析構函式virtual與非virtual區別 作為通常的原則,如果乙個類定義了虛函式,那麼它的析構函式就應當是virtual的。因為定義了虛函式則隱含著 這個類會被繼承,並且會通過基類的指標指向子類物件,從而得到多型性。這個類可能會被繼承,並且會通過基類的指標指向子類物件 因此基類的析構函式是否為虛...