思考virtual析構

2021-04-01 20:18:26 字數 2296 閱讀 5817

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_1virtual修飾,所以以後所有它的派生類用自己的析構函式指標重寫虛函式表裡的對應的位置,以至出現與第一種情況相同的結果!

有一種情況沒有表達,就是如果定義如下:

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的。因為定義了虛函式則隱含著 這個類會被繼承,並且會通過基類的指標指向子類物件,從而得到多型性。這個類可能會被繼承,並且會通過基類的指標指向子類物件 因此基類的析構函式是否為虛...