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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

搞清虚析构函数的使用场合

發布時間:2024/9/21 编程问答 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 搞清虚析构函数的使用场合 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

疑問:什么情況下必須用虛析構?


先看個例子:


#include?<iostream>?? class?A?? {?? public:??A(){};??~A()??{??std::cout?<<?"~A"?<<?std::endl;??};?? private:??int?a;?? };??class?B?:?public?A?? {?? public:??B(){};??~B()??{??std::cout?<<?"~B"?<<?std::endl;??}?? private:??int?b;?? };??int?main()??? {???????B?b;???????return?0;?? }

? ??

調試發現,窗口依次輸出: ~B 和 ~A,也就是說,B類對象b析構的時候,先調用了B類的析構函數,然后調用了基類的析構函數。


如果 main 函數中的代碼,替換為如下呢?


int?main()? {?B?*pb?=?new?B();?delete?pb;?return?0;? }

? ??

你會發現,還是依次輸出了 ~B 和 ~A,也就是說,當使用子類指針指向子類對象的時候,析構的時候,依然會依次調用子類和基類的析構函數。


如果 main 函數中的代碼,替換為如下呢?


int?main()? {?A?*?pa?=?new?B();?delete?pa;?return?0;? }


調試發現,這份代碼,只會輸出 ~A, 哦,到此終于明白了,當用基類指針指向派生類對象時,如果基類析構函數不設置為 virtual 的話,則在 delete 基類指針的時候,無法成功調用子類的析構函數。這才是虛析構函數發揮作用的真正場合。

? ??

上述代碼解決方法: 把基類 A 的析構函數設置為 virtual,則可以成功實現delete pa 的時候依次調用B類和A類的析構函數了。

? ??

那么,進一步講,我們是否應該把所有類的析構函數都設置為虛析構呢?

? ??

不應該,這樣設置不合理,只有在該類可能作為基類的情況下,并且可能使用到多態特性的時候,才有必要把基類的析構函數設置為虛析構,否則,沒有必要,因為設置為虛析構會產生額外的開銷,即下一個問題:

? ??

一個類如果把析構函數設置為 virtual 是否也會產生虛函數表?

? ??

我們把上述代碼稍微改一下:?


class?A?? {?? public:??A(){};??~A()??{??std::cout?<<?"~A"?<<?std::endl;??};??void?test()?{?std::cout?<<?"~test"?<<?std::endl;?}? private:??int?a;?? };??int?main()?? {??std::cout?<<?sizeof(A)?<<?std::endl;?? }


如果 ~A 前面不加 virtual 則輸出的結果是: 4

如果 ~A 前面加 virtual 則輸出的結果是: 8?


可以得出如下結論:


(1) 如果類沒有virtual成員函數時,類的大小由數據成員大小決定

(2) 虛析構函數也會使類產生虛函數表,并且虛函數表的大小是 4 字節


本文轉自 Jhuster 51CTO博客,原文鏈接:http://blog.51cto.com/ticktick/961418,如需轉載請自行聯系原作者

總結

以上是生活随笔為你收集整理的搞清虚析构函数的使用场合的全部內容,希望文章能夠幫你解決所遇到的問題。

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