今天小編給大家分享一下C++中的虛析構(gòu)函數(shù)有什么用的相關(guān)知識點,內(nèi)容詳細(xì),邏輯清晰,相信大部分人都還太了解這方面的知識,所以分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后有所收獲,下面我們一起來了解一下吧。
創(chuàng)新互聯(lián)是一家專業(yè)提供石城企業(yè)網(wǎng)站建設(shè),專注與網(wǎng)站設(shè)計、成都網(wǎng)站制作、HTML5、小程序制作等業(yè)務(wù)。10年已為石城眾多企業(yè)、政府機構(gòu)等服務(wù)。創(chuàng)新互聯(lián)專業(yè)的建站公司優(yōu)惠進行中。一.虛析構(gòu)函數(shù)的作用
總的來說虛析構(gòu)函數(shù)是為了避免內(nèi)存泄露,而且是當(dāng)子類中會有指針成員變量時才會使用得到的。也就說虛析構(gòu)函數(shù)使得在刪除指向子類對象的基類指針時可以調(diào)用子類的析構(gòu)函數(shù)達(dá)到釋放子類中堆內(nèi)存的目的,而防止內(nèi)存泄露的.
我們知道,用C++開發(fā)的時候,用來做基類的類的析構(gòu)函數(shù)一般都是虛函數(shù)??墒?,為什么要這樣做呢?下面用一個小例子來說明:
#include<iostream> using namespace std; class ClxBase { public: ClxBase() {}; virtual ~ClxBase() { cout<<"delete ClxBase"<<endl; }; virtual void DoSomething() { cout << "Do something in class ClxBase!" << endl; }; }; class ClxDerived : public ClxBase { public: ClxDerived() {}; ~ClxDerived() { cout << "Output from the destructor of class ClxDerived!" << endl; }; void DoSomething() { cout << "Do something in class ClxDerived!" << endl; }; }; int main(int argc, char const* argv[]) { ClxBase *pTest = new ClxDerived; pTest->DoSomething(); delete pTest; return 0; }
但是,如果把類ClxBase析構(gòu)函數(shù)前的virtual去掉,那輸出結(jié)果就是下面的樣子了:
沒有調(diào)動子類的析構(gòu)函數(shù)
也就是說,類ClxDerived的析構(gòu)函數(shù)根本沒有被調(diào)用!一般情況下類的析構(gòu)函數(shù)里面都是釋放內(nèi)存資源,而析構(gòu)函數(shù)不被調(diào)用的話就會造成內(nèi)存泄漏。我想所有的C++程序員都知道這樣的危險性。當(dāng)然,如果在析構(gòu)函數(shù)中做了其他工作的話,那你的所有努力也都是白費力氣。
所以,文章開頭的那個問題的答案就是--這樣做是為了當(dāng)用一個基類的指針刪除一個派生類的對象時,派生類的析構(gòu)函數(shù)會被調(diào)用。
當(dāng)然,并不是要把所有類的析構(gòu)函數(shù)都寫成虛函數(shù)。因為當(dāng)類里面有虛函數(shù)的時候,編譯器會給類添加一個虛函數(shù)表,里面來存放虛函數(shù)指針,這樣就會增加類的存儲空間。所以,只有當(dāng)一個類被用來作為基類的時候,才把析構(gòu)函數(shù)寫成虛函數(shù)。
總結(jié)一下虛析構(gòu)函數(shù)的作用:
(1)如果父類的析構(gòu)函數(shù)不加virtual關(guān)鍵字
當(dāng)父類的析構(gòu)函數(shù)不聲明成虛析構(gòu)函數(shù)的時候,當(dāng)子類繼承父類,父類的指針指向子類時,delete掉父類的指針,只調(diào)動父類的析構(gòu)函數(shù),而不調(diào)動子類的析構(gòu)函數(shù)。
(2)如果父類的析構(gòu)函數(shù)加virtual關(guān)鍵字
當(dāng)父類的析構(gòu)函數(shù)聲明成虛析構(gòu)函數(shù)的時候,當(dāng)子類繼承父類,父類的指針指向子類時,delete掉父類的指針,先調(diào)動子類的析構(gòu)函數(shù),再調(diào)動父類的析構(gòu)函數(shù)。
二.虛析構(gòu)函數(shù)的原理分析
#include<iostream> using namespace std; class Base { public: Base(){cout<<"create Base"<<endl;} virtual ~Base(){cout<<"delete Base"<<endl;} }; class Der : public Base { public: Der(){cout<<"create Der"<<endl;} ~Der(){cout<<"Delete Der"<<endl;} }; int main(int argc, char const* argv[]) { Base *b = new Der; delete b; return 0; }
從創(chuàng)建講起,用gdb調(diào)試你會發(fā)現(xiàn),
(1)先調(diào)用父類的構(gòu)造函數(shù),再調(diào)用子類的構(gòu)造函數(shù),
這里有一個問題:父類的構(gòu)造函數(shù)/析構(gòu)函數(shù)與子類的構(gòu)造函數(shù)/析構(gòu)函數(shù)會形成多態(tài),但是當(dāng)父類的構(gòu)造函數(shù)/析構(gòu)函數(shù)即使被聲明virtual,子類的構(gòu)造/析構(gòu)方法仍無法覆蓋父類的構(gòu)造方法和析構(gòu)方法。這是由于父類的構(gòu)造函數(shù)和析構(gòu)函數(shù)是子類無法繼承的,也就是說每一個類都有自己獨有的構(gòu)造函數(shù)和析構(gòu)函數(shù)。
(2)而由于父類的析構(gòu)函數(shù)為虛函數(shù),所以子類會在所有屬性的前面形成虛表,而虛表內(nèi)部存儲的就是父類的虛函數(shù)
即使子類也有虛函數(shù),但是由于是單繼承,所以也只有一張?zhí)摫?,這在上一篇博客多態(tài)中講到過。
執(zhí)行 Base *b = new Der;之后b的最終形態(tài)
(3)當(dāng)delete父類的指針時,由于子類的析構(gòu)函數(shù)與父類的析構(gòu)函數(shù)構(gòu)成多態(tài),所以得先調(diào)動子類的析構(gòu)函數(shù);之所以再調(diào)動父類的析構(gòu)函數(shù),是因為delete的機制所引起的,delete 父類指針?biāo)傅目臻g,要調(diào)用父類的析構(gòu)函數(shù)。
以上就是“C++中的虛析構(gòu)函數(shù)有什么用”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家閱讀完這篇文章都有很大的收獲,小編每天都會為大家更新不同的知識,如果還想學(xué)習(xí)更多的知識,請關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道。
本文題目:C++中的虛析構(gòu)函數(shù)有什么用-創(chuàng)新互聯(lián)
網(wǎng)頁路徑:http://www.rwnh.cn/article0/ccijoo.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供企業(yè)網(wǎng)站制作、移動網(wǎng)站建設(shè)、域名注冊、動態(tài)網(wǎng)站、微信小程序、網(wǎng)站設(shè)計
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)
猜你還喜歡下面的內(nèi)容