日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 >

C++中基类的析构函数为什么要用virtual虚析构函数

發布時間:2025/7/14 21 豆豆
生活随笔 收集整理的這篇文章主要介紹了 C++中基类的析构函数为什么要用virtual虚析构函数 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

知識背景

? ? ? ? ?要弄明白這個問題,首先要了解下C++中的動態綁定。?

? ? ? ? ?關于動態綁定的講解,請參閱: ?C++中的動態類型與動態綁定、虛函數、多態實現

正題

? ? ? ? ?直接的講,C++中基類采用virtual虛析構函數是為了防止內存泄漏。具體地說,如果派生類中申請了內存空間,并在其析構函數中對這些內存空間進行釋放。假設基類中采用的是非虛析構函數,當刪除基類指針指向的派生類對象時就不會觸發動態綁定,因而只會調用基類的析構函數,而不會調用派生類的析構函數。那么在這種情況下,派生類中申請的空間就得不到釋放從而產生內存泄漏。所以,為了防止這種情況的發生,C++中基類的析構函數應采用virtual虛析構函數。

示例代碼講解

現有Base基類,其析構函數為非虛析構函數。Derived1和Derived2為Base的派生類,這兩個派生類中均有以string* 指向存儲其name的地址空間,name對象是通過new創建在堆上的對象,因此在析構時,需要顯式調用delete刪除指針歸還內存,否則就會造成內存泄漏。

class Base {public: ~Base() {cout << "~Base()" << endl; } }; class Derived1 : public Base {public:Derived1():name_(new string("NULL")) {}Derived1(const string& n):name_(new string(n)) {}~Derived1() {delete name_;cout << "~Derived1(): name_ has been deleted." << endl;}private:string* name_; };class Derived2 : public Base {public:Derived2():name_(new string("NULL")) {}Derived2(const string& n):name_(new string(n)) {}~Derived2() {delete name_;cout << "~Derived2(): name_ has been deleted." << endl;}private:string* name_; };

我們看下面對其析構情況進行測試:

int main() {Derived1* d1 = new Derived1();Derived2 d2 = Derived2("Bob");delete d1;return 0; }

d1為Derived1類的指針,它指向一個在堆上創建的Derived1的對象;d2為一個在棧上創建的對象。其中d1所指的對象需要我們顯式的用delete調用其析構函數;d2對象在其生命周期結束時,系統會自動調用其析構函數。看下其運行結果:

剛才我們說,Base基類的析構函數并不是虛析構函數,現在結果顯示,派生類的析構函數被調用了,正常的釋放了其申請的內存資源。這兩者并不矛盾,因為無論是d1還是d2,兩者都屬于靜態綁定,而且其靜態類型恰好都是派生類,因此,在析構的時候,即使基類的析構函數為非虛析構函數,也會調用相應派生類的析構函數。

下面我們來看下,當發生動態綁定時,也就是當用基類指針指向派生類,這時候采用delete顯式刪除指針所指對象時,如果Base基類的析構函數沒有virtual,會發生什么情況?

int main() {Base* base[2] = {new Derived1(),new Derived2("Bob") };for (int i = 0; i != 2; ++i) {delete base[i]; }return 0; }


? ? ? ? 從上面結果我們看到,盡管派生類中定義了析構函數來釋放其申請的資源,但是并沒有得到調用。原因是基類指針指向了派生類對象,而基類中的析構函數卻是非virtual的,之前講過,虛函數是動態綁定的基礎。現在析構函數不是virtual的,因此不會發生動態綁定,而是靜態綁定,指針的靜態類型為基類指針,因此在delete時候只會調用基類的析構函數,而不會調用派生類的析構函數。這樣,在派生類中申請的資源就不會得到釋放,就會造成內存泄漏,這是相當危險的:如果系統中有大量的派生類對象被這樣創建和銷毀,就會有內存不斷的泄漏,久而久之,系統就會因為缺少內存而崩潰。

? ? ? ? 也就是說,在基類的析構函數為非虛析構函數的時候,并不一定會造成內存泄漏;當派生類對象的析構函數中有內存需要收回,并且在編程過程中采用了基類指針指向派生類對象,如為了實現多態,并且通過基類指針將該對象銷毀,這時,就會因為基類的析構函數為非虛析構函數而不觸發動態綁定,從而沒有調用派生類的析構函數而導致內存泄漏。

? ? ? ? 因此,為了防止這種情況下內存泄漏的發生,最好將基類的析構函數寫成virtual虛析構函數。

下面把Base基類的析構函數改為虛析構函數:

class Base {public: virtual ~Base() {cout << "~Base()" << endl; } };

再看下其運行結果:


這樣就會實現動態綁定,派生類的析構函數就會得到調用,從而避免了內存泄漏。

?

故:?繼承時,要養成的一個好習慣就是,基類析構函數中,加上virtual。

轉自:http://blog.csdn.net/iicy266/article/details/11906457

轉載于:https://www.cnblogs.com/willhua/p/6785158.html

總結

以上是生活随笔為你收集整理的C++中基类的析构函数为什么要用virtual虚析构函数的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 亚洲第一页乱 | 在线国产观看 | 日韩免费av | 夜夜躁日日躁狠狠久久av | 99精品视频国产 | 总裁憋尿呻吟双腿大开憋尿 | 91丝袜呻吟高潮美腿白嫩在线观看 | 国产女同在线观看 | 五月天视频网 | 性色av一区二区三区红粉影视 | 天堂中文在线8 | 久久亚洲AV成人无码国产野外 | 小色哥网站| 国产欧美精品一区二区色综合朱莉 | 亚洲专区在线播放 | 亚洲h片| 中文字幕第88页 | gav成人| 国产精品theporn88 | 很黄的网站在线观看 | 国产成人精品一区二区色戒 | 欧美日韩一级大片 | 日韩av在线免费看 | 欧美成人性生活片 | 黑人一区二区三区四区五区 | 国产九色在线播放九色 | 在线成人黄色 | sm在线看 | 中文视频在线观看 | 亚洲首页| 免费的黄网站 | 国产一区99| 黄色一级片免费播放 | 在线免费黄网 | 国产美女精品一区二区三区 | 麻豆传媒在线播放 | 涩婷婷| 精品久久99 | 亚洲国产成人91精品 | 涩涩的视频在线观看 | 日韩福利电影在线观看 | 日韩a级一片 | 国产精品成人一区二区网站软件 | 99免费视频 | 91精品国产综合久久国产大片 | 久久合合| 校园春色综合 | 日韩中文第一页 | 琪琪原网址| 亚洲美女自拍视频 | 天天槽| 农村妇女一区二区 | 国产性猛交╳xxx乱大交一区 | 好吊色综合| 久久久久久久蜜桃 | 日本理论视频 | 伊人精品一区二区三区 | 日韩片在线观看 | 少妇高潮av久久久久久 | 毛片网站有哪些 | 潘金莲一级淫片免费放动漫 | 黄色喷水网站 | 成人a毛片| 9久久精品 | 亚洲好骚综合 | 又欲又污又肉又黄短文 | 三年在线观看视频 | a级一级片 | 新婚若妻侵犯中文字幕 | 麻豆一区产品精品蜜桃的特点 | 欧美日韩中文字幕一区二区三区 | www.久久爱| 日韩在线专区 | av秋霞| 亚洲欧美影院 | 成年人看片网站 | 成人蜜桃av | 欧美激情视频在线观看 | 国产一区日韩 | 日批视频在线免费看 | 国产sm在线观看 | 中文字幕永久在线播放 | 美女靠逼视频网站 | av免费毛片 | www.国产一区二区三区 | 丁香视频在线观看 | 影音先锋中文字幕在线 | 欧洲精品在线观看 | 国产成人精品免费看视频 | 国产精品一区二区三区在线播放 | 男生吃小头头的视频 | 国产精品第1页 | 日韩在线一 | 最近中文字幕mv免费高清在线 | 精品国产乱子伦一区二区 | 亚欧综合在线 | 亚洲精品视频在线看 | 深爱激情久久 | 国产成人不卡 |