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:;
00401413movecx,dword ptr [ebp-4]
00401416call@ilt+145(zf5_2::~zf5_2) (00401096)
0040141bpopedi
0040141cpopesi
0040141dpopebx
0040141eaddesp,44h
00401421cmpebp,esp
00401423call__chkesp (00401e00)
00401428movesp,ebp
0040142apopebp
0040142bret
思考virtual析構
author zfive5 zhaozidong email zfive5 yahoo.com.cn 最近同住的朋友忙著找工作,他c 的問題看了一堆,我也受其影響複習了一些c 知識,virtual析構聽他說 點播率還挺高的 所以拿來仔細研究,求個深解!首先,定義3個類,注意了析構函式的virtual...
virtual析構函式
當派生類物件撤銷時,一般先呼叫派生類的析構函式,然後再呼叫基類的析構函式。include using namespace std class base class derived public base int main void 執行結果 呼叫基類base的析構函式 如果在主函式中用new運算子建...
析構函式virtual與非virtual區別
析構函式virtual與非virtual區別 作為通常的原則,如果乙個類定義了虛函式,那麼它的析構函式就應當是virtual的。因為定義了虛函式則隱含著 這個類會被繼承,並且會通過基類的指標指向子類物件,從而得到多型性。這個類可能會被繼承,並且會通過基類的指標指向子類物件 因此基類的析構函式是否為虛...