析構函數virtual與非virtual區別

作為通常的原則,如果一個類定義了虛函數,那么它的析構函數就應當是virtual的。因為定義了虛函數則隱含著:這個類會被繼承,并且會通過基類的指針指向子類對象,從而得到多態性。?? 這個類可能會被繼承,并且會通過基類的指針指向子類對象”,因此基類的析構函數是否為虛將決定子類的對象是否被析構

示例代碼:

#include?<iostream.h>

struct?A
{
????
virtual?~A()?{cout<<"~A()\n";}
}
;

struct?B:?public?A
{
????
~B()?{cout<<"~B()\n";}
}
;

void?main()
{
????A
*?p?=?new?B;
????delete?p;
}


如果 A的析構函數不是virtual的,那么此時就不是先調用B的析構函數再調用A的析構函數。
Output:
~A();?
如果A?? 的析構函數為virtual,則先~B(),再~A()??
Output:
~B();
~A();
?????? 類如果會被派生的話,析構函數一般都應該定義為virtual的,主要不是防止內存泄露,而是為了正確的析構。如果是個封閉類(即不再被派生),就不要定義為virtual的。虛函數畢竟耗費較大的。

不用virtual 的幾種情況:
? 1、作為非公有基類。僅作為?? private?? base?? class?? 使用的?? class?? 不需要使用虛擬析構函數??
? 2、不作為接口使用的基類。??
? 3.?? 如果你可以保證這個類不被public繼承(private/protected繼承的話,在非friend函數/類中就無法用基類指針指向派生類了)??
? 4.?? 如果它的所有派生類(包括派生類的派生類)的析構函數都是trivial的(這里的trivial指的是在程序員的層次什么事也不做)??
? 5.?? 如果不需要用基類的指針指向派生類的對象??
? 在這五種情況下,不把析構函數聲明為virtual都是可以的,何況效率會高一些——但前提是你得保證前提的成立——不過這些保證常常是很難100%的:誰能保證別人在派生你的類的時候,析構函數是trivial的,或者別人不用你提供的基類的指針指向派生類對象?這些常常是很難得到保證的。??

聲明基類的析構函數為virtual并非總是為了防止memory?? leak?? 另外這也只是作為一般的原則(基類中有虛函數則把其析構函數聲明為virtual)。如果你的析構函數什么事也不作,從效果上來說,不聲明為virtual也無妨





為什么C++析構函數前面有時需要 virtual

#include <iostream>

using namespace std;class Base{public:virtual ~Base() {cout<<"~B"<<endl;}
};class Derived:public Base{public:virtual ~Derived() {cout<<"~D"<<endl;}
};int main (){Base *b=new Derived;delete b;
}
?
復制代碼

?以上代碼執行結果是:

~D

~B

?

對于析構函數使用虛函數的解釋,是這樣的,因為是使用語句  Base *b=new Derived;來創建的對象b,如果,我們不把析構函數聲明為虛函數,那么實際上,在對象生命周期結束時,調用的將只是基類Base的析構函數,而派生類Derived的析構函數將是不調用的,你可以試驗一下,此時,只打印~B。而我們為了正確地釋放對象,所以要將析構函數聲明為虛函數,這時,基類和派生類的析構函數就都會調用了。


本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/452389.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/452389.shtml
英文地址,請注明出處:http://en.pswp.cn/news/452389.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Python:字典列表字符串方法測試

測試的一些Python中的關于字典、列表、字符串的使用方法&#xff0c;放在這里備查。整個測試代碼和說明如下&#xff1a; # -*- coding: utf-8 -*- """Python:函數中全是指針傳遞&#xff0c;而任何變量都是給予一個指針指向一個內存空間"""impo…

什么是確認測試

確認測試也稱為驗收測試&#xff0c;它的目標是驗證軟件的有效性。 通常&#xff0c;驗證指的是保證軟件正確地實現了某個特定要求的一系列活動&#xff1b;確認指的是為了保證軟件確實滿足了用戶需求而進行的一系列活動。 軟件有效性的一個簡單定義是&#xff1a;如果軟件的功…

Diango博客--17.統計各個分類和標簽下的文章數

文章目錄0.思路引導1.Model 回顧2.數據庫數據聚合3.使用 Annotate4.在模板中引用新增的屬性0.思路引導 在我們的博客側邊欄有分類列表和標簽列表&#xff0c;顯示博客已有的全部文章分類。現在想在分類名和標簽名后顯示該分類或者標簽下有多少篇文章&#xff0c;該怎么做呢&am…

HTTP協議中request報文請求方法和狀態響應碼

一個HTTP請求報文由4部分組成&#xff1a; 請求行&#xff08;request line&#xff09;請求頭部&#xff08;header&#xff09;空行請求數據下圖給出了請求報文的一般格式&#xff1a; 請求行中包括了請求方法&#xff0c;常見的請求方法有&#xff1a; GET&#xff1a;從服務…

計算機無法安裝64位操作系統,為什么我的win7旗艦版service Pack 1 64位操作系統 無法安裝(KB2670838) 這個更新...

您好&#xff01;我了解到您遇到關于這邊的問題請問無法安裝是否出現了什么錯誤代碼提示呢&#xff1f;請參考以下的步驟解決按WindowsR打開cmd里使用下面的命令關閉相關的一些服務&#xff1a;net stop wuauservnet stop cryptSvcnet stop bitsnet stop msiserver完成后&#…

bmon:一個強大的網絡帶寬監視和調試工具

bmon 是類 Unix 系統中一個基于文本&#xff0c;簡單但非常強大的 網絡監視和調試工具&#xff0c;它能抓取網絡相關統計信息并把它們以用戶友好的格式展現出來。它是一個可靠高效的帶寬監視和網速估測工具。 它能使用各種輸入模塊讀取輸入&#xff0c;并以各種輸出模式顯示輸出…

函數的調用規則(__cdecl,__stdcall,__fastcall,__pascal)

關于函數的調用規則&#xff08;調用約定&#xff09;&#xff0c;大多數時候是不需要了解的&#xff0c;但是如果需要跨語言的編程&#xff0c;比如VC寫的dll要delphi調用&#xff0c;則需要了解。 microsoft的vc默認的是__cdecl方式&#xff0c;而windows API則是__stdcall&a…

Linux 下的/usr/bin /usr/sbin /usr/local/bin /usr/local/sbin區別

1、/bin 是所有用戶都可以訪問并執行的可執行程序。包括超級用戶及一般用戶。 供所有用戶&#xff08;包括root用戶和一般用戶&#xff09;使用的基本命令&#xff0c;主要有cat,chmod,date,cp,bash等等常用的命令。 2、/usr/bin&#xff1a;系統預裝的可執行程序&#xff0c;…

alpha測試和betal測試

如果一個軟件是為許多客戶開發的&#xff08;例如&#xff0c;向大眾公開出售的盒裝軟件產品&#xff09;&#xff0c;那么絕大多數軟件開發商都使用被稱為Alpha測試和Beta測試的過程&#xff0c;來發現那些看起來只有最終用戶才能發現的錯誤。 Alpha測試由用戶在開發者的場所進…

計算機d盤無法格式化,四種方法解決D盤無法格式化問題

不少朋友系統出現故障&#xff0c;幾乎都是選擇重裝系統的方法來解決問題。系統重裝后&#xff0c;不少朋友覺得D盤沒有什么重要的東西&#xff0c;就想將其格式化&#xff0c;可是系統出現windows無法格式該驅動器的提示&#xff0c;這是怎么回事呢&#xff1f;D盤無法格式化要…

sqlserver視圖

作用 ①簡化了操作&#xff0c;把經常使用的數據定義為視圖。 ②安全性&#xff0c;用戶只能查詢和修改能看到的數據。 ③邏輯上的獨立性&#xff0c;屏蔽了真實表的結構帶來的影響。 對視圖的修改&#xff1a;單表視圖一般用于查詢和修改&#xff0c;會改變基本表的數據&#…

非root用戶sudo_ssh免密鑰

非root用戶sudo_ssh免密鑰 目標&#xff1a;從服務器上ssh登陸后sudo免密鑰執行相應的命令 環境介紹&#xff1a; 192.168.65.128 my1-222 192.168.65.129 my2-223 192.168.65.130 web224# 步驟一&#xff1a; # 每個節點執行(不是必須&#xff0c;但是建議這樣做) cat …

復旦大學和吉大計算機考研選哪個,2016復旦大學VS吉林大學 基于排名角度的比較?...

復旦大學好還是吉林大學好首先&#xff0c;2016復旦大學好還是吉林大學好是近日問得較多的問題之一&#xff0c;小伙伴們有的從吉林大學和復旦大學的地理位置優勢角度進行分析&#xff0c;有的從吉林大學和復旦大學的強勢專業角度進行PK&#xff0c;有的甚至從吉林大學和復旦大…

Diango博客--18.使用 Fabric 自動化部署 Django 項目

文章目錄1.本地安裝 Fabric2.部署過程回顧3.完善項目配置4.修改 BASE_DIR 配置項5.設置 Supervisor 環境變量6.編寫 Fabric 腳本7.執行 Fabric 自動部署腳本1.本地安裝 Fabric $ pipenv install fabric --dev 報錯&#xff1a; An error occurred while installing django-pure…

白盒測試詳解

通常把測試數據和預期的輸出結果稱為測試用例。 &#xff08;一&#xff09;邏輯覆蓋 是對一系列測試過程的總稱&#xff0c;這組測試過程逐漸進行越來越完整的通路測試。 1.語句覆蓋 語句覆蓋的含義是&#xff0c;選擇足夠多的測試數據&#xff0c;使被測程序中每個語句至少…

git 的安裝以及使用:是一個開源的分布式版本控制系統,可以對項目進行版本管理。 早期是linux之父用來管理linux系統源代碼的(linux是和windows一樣操作系統 開源免費的操作...

## 總結 - 學會使用基本的git命令 管理源代碼- 學會去github創建倉庫 并將代碼上傳到github的倉庫 (有待完成 回家有網再push)- 了解本地的.git和服務器github的.git的關系 是兩個倉庫 一個是本地 一個是服務器 需要使用一句命令來關聯 git remote add origin 遠端的.git的地址…

自斷前程,未來80%IT工作將實現自動化

技術人員革了自己的命&#xff1f; 在上周的Structure大會上&#xff0c;硅谷著名風險投資人、億萬富翁唯諾德稱未來80%的IT工作都將被AI系統所替代。不過&#xff0c;唯諾德好像并不擔心&#xff0c;相反他補充了一句“我覺得很興奮。”唯諾德表示自己并非危言聳聽&#xff0c…

2013計算機二級試題,2013全國計算機二級上機考試試題46-100套試題

*第46 套上機考試試題一、基本操作題**請根據以下各小題的要求設計Visual Basic 應用程序(包括界面和代碼)。(1)在名稱為Form1、標題為“框架練習”的窗體上*畫一個名稱為Frame1、標題為“字體”的框架控件&#xff1b;在框架中畫兩個單選按鈕&#xff0c;名稱分別為Option1、O…

黑盒測試詳解

黑盒測試著重測試軟件功能。黑盒測試并不能取代白盒測試&#xff0c;它是與白盒測試互補的測試方法&#xff0c;它很可能發現白盒測試不易發現的其他類型的錯誤。白盒測試在測試過程的早期階段進行&#xff0c;而黑盒測試主要用于測試過程的后期。 黑盒測試力圖發現下述類型的…

linux中rpm、yum、apt-get的關系

Linux中yum和apt-get用法及區別 一般來說著名的linux系統基本上分兩大類&#xff1a; 1.RedHat系列&#xff1a;Redhat、Centos、Fedora等 2.Debian系列&#xff1a;Debian、Ubuntu等 RedHat 系列 1 常見的安裝包格式 rpm包,安裝rpm包的命令是“rpm -參數” 2 包管理工具 y…