思考virtual析構

2021-08-22 01:41:46 字數 2029 閱讀 5554

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: ;

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