欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

C++中為何推薦要把基類析構(gòu)函數(shù)設置成虛函數(shù)

 更新時間:2022年12月28日 09:24:40   作者:我的博爾赫斯  
這篇文章主要介紹了C++中為何推薦要把基類析構(gòu)函數(shù)設置成虛函數(shù)問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教

C++何推薦要把基類析構(gòu)函數(shù)設置成虛函數(shù)

在C++中常聽老師講要把基類析構(gòu)函數(shù)聲明成虛函數(shù),這是因為要防止使用基類指針在調(diào)用派生類對象析構(gòu)函數(shù)時,觸發(fā)靜態(tài)綁定,調(diào)用不到派生類的析構(gòu)函數(shù),導致內(nèi)存泄漏

//Base表示基類
//Derive表示派生類
Base* ptr = new Derive d;

在這里如果沒有把基類析構(gòu)函數(shù)聲明成虛函數(shù),那么就沒有構(gòu)成多態(tài),那么編譯器只會去調(diào)用Base的析構(gòu)函數(shù)而非Derive

C++中析構(gòu)函數(shù)為虛函數(shù)問題

1、析構(gòu)函數(shù)是否定義為虛函數(shù)的區(qū)別

(1)析構(gòu)函數(shù)定義為虛函數(shù)時:基類指針可以指向派生類的對象(多態(tài)性),如果刪除該指針delete []p;就會調(diào)用該指針指向的派生類析構(gòu)函數(shù),而派生類的析構(gòu)函數(shù)又自動調(diào)用基類的析構(gòu)函數(shù),這樣整個派生類的對象完全被釋放。

(2)析構(gòu)函數(shù)不定義為虛函數(shù)時:編譯器實施靜態(tài)綁定,在刪除基類指針時,只會調(diào)用基類的析構(gòu)函數(shù)而不調(diào)用派生類析構(gòu)函數(shù),這樣就會造成派生類對象析構(gòu)不完全。

下面看幾個例子

2、派生類指針操作派生類對象,基類析構(gòu)函數(shù)不是虛函數(shù)

#include<iostream>
using namespace std;
class ClxBase{
public:
	ClxBase() {};
	~ClxBase() { cout << "Output from the destructor of class ClxBase!" << endl; };
 
	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(){
    ClxDerived *p = new ClxDerived;		// 派生類指針操作派生類對象
	p->DoSomething();
	delete p;
	system("pause");
	return 0;
}

注:派生類指針操作派生類對象,基類析構(gòu)函數(shù)不是虛函數(shù),此時會先是否派生類的資源,再釋放基類的資源,這里資源就不會出現(xiàn)泄漏的情況。

3、基類指針操作派生類對象,基類析構(gòu)函數(shù)不是虛函數(shù)

#include<iostream>
using namespace std;
class ClxBase{
public:
	ClxBase() {};
	~ClxBase() { cout << "Output from the destructor of class ClxBase!" << endl; };
 
	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(){
	ClxBase *p = new ClxDerived;		// 基類指針操作派生類對象
	p->DoSomething();
	delete p;
	system("pause");
	return 0;
}

注:基類指針操作派生類對象,基類析構(gòu)函數(shù)不是虛函數(shù):此時只是釋放了基類的資源,而沒有調(diào)用派生類的析構(gòu)函數(shù)。調(diào)用dosomething()函數(shù)執(zhí)行的也是基類定義的函數(shù)。這樣的刪除只能夠刪除基類對象,而不能刪除子類對象,形成了刪除一半形象,造成內(nèi)存泄漏。

4、基類指針操作派生類對象,基類析構(gòu)函數(shù)是虛函數(shù)

#include<iostream>
using namespace std;
class ClxBase{
public:
	ClxBase() {};
// 定義為虛函數(shù)
	virtual ~ClxBase() { cout << "Output from the destructor of class 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(){
	ClxBase *p = new ClxDerived;		// 基類指針操作派生類對象
	p->DoSomething();
	delete p;
	system("pause");
	return 0;
}

注:基類指針操作派生類對象,基類析構(gòu)函數(shù)是虛函數(shù):此時釋放了派生類的資源,再調(diào)用基類的析構(gòu)函數(shù)。調(diào)用dosomething()函數(shù)執(zhí)行的也是派生類定義的函數(shù)。

在公有繼承中,基類對派生類及其對象的操作,只能影響到那些從基類繼承下來的成員。如果想要用基類對非繼承成員進行操作,則要把基類的這個函數(shù)定義為虛函數(shù)。

析構(gòu)函數(shù)自然也應該如此:如果它想析構(gòu)子類中的重新定義或新的成員及對象,當然也應該聲明為虛的。

5、基類析構(gòu)函數(shù)定義為虛函數(shù)的情況

如果不需要基類對派生類及對象進行操作,則不能定義虛函數(shù),因為這樣會增加內(nèi)存開銷.當類里面有定義虛函數(shù)的時候,編譯器會給類添加一個虛函數(shù)表,里面來存放虛函數(shù)指針,這樣就會增加類的存儲空間。所以,只有當一個類被用來作為基類的時候,并且有使用到基類指針操作派生類的情況時,才把析構(gòu)函數(shù)寫成虛函數(shù)。

總結(jié)

以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關文章

  • opencv車道線檢測的實現(xiàn)方法

    opencv車道線檢測的實現(xiàn)方法

    這篇文章主要介紹了opencv車道線檢測的實現(xiàn)方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2019-08-08
  • Objective-C限制函數(shù)調(diào)用的頻率詳解

    Objective-C限制函數(shù)調(diào)用的頻率詳解

    這篇文章主要給大家介紹了關于Objective-C限制函數(shù)調(diào)用的頻率的相關資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧。
    2017-12-12
  • C語言數(shù)據(jù)結(jié)構(gòu)經(jīng)典10大排序算法刨析

    C語言數(shù)據(jù)結(jié)構(gòu)經(jīng)典10大排序算法刨析

    這篇文章主要介紹了C語言中常用的10種排序算法及代碼實現(xiàn),開發(fā)中排序的應用需要熟練的掌握,因為是基礎內(nèi)容,那C語言有哪些排序算法呢?本文小編就來詳細說說,需要的朋友可以參考一下
    2022-02-02
  • C++實現(xiàn)LeetCode(67.二進制數(shù)相加)

    C++實現(xiàn)LeetCode(67.二進制數(shù)相加)

    這篇文章主要介紹了C++實現(xiàn)LeetCode(67.二進制數(shù)相加),本篇文章通過簡要的案例,講解了該項技術的了解與使用,以下就是詳細內(nèi)容,需要的朋友可以參考下
    2021-07-07
  • 最小生成樹算法之Prim算法

    最小生成樹算法之Prim算法

    這篇文章主要講解了普里姆算法(Prim算法),圖論中的一種算法,可在加權(quán)連通圖里搜索最小生成樹,需要的朋友可以參考下
    2015-07-07
  • 一起來學習C++的構(gòu)造和析構(gòu)

    一起來學習C++的構(gòu)造和析構(gòu)

    這篇文章主要為大家詳細介紹了C++構(gòu)造和析構(gòu),文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2022-03-03
  • C++實現(xiàn)哈夫曼樹編碼解碼

    C++實現(xiàn)哈夫曼樹編碼解碼

    這篇文章主要為大家詳細介紹了C++實現(xiàn)哈夫曼樹編碼解碼,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-04-04
  • C++定時器Timer在項目中的使用方法

    C++定時器Timer在項目中的使用方法

    這篇文章主要給大家介紹了關于C++定時器Timer在項目中的基本使用方法,文中通過示例代碼介紹的非常詳細,對大家學習或者使用C++具有一定的參考學習價值,需要的朋友們下面來一起學習學習吧
    2019-05-05
  • Qt自定義表頭實現(xiàn)過濾功能的方法

    Qt自定義表頭實現(xiàn)過濾功能的方法

    這篇文章主要個給大家介紹了關于Qt自定義表頭實現(xiàn)過濾功能的相關資料,文中通過示例代碼介紹的非常詳細,對大家學習或者使用Qt具有一定的參考學習價值,需要的朋友們下面來一起學習學習吧
    2019-07-07
  • C++中VTK9.3.0刻度標簽重疊的問題記錄

    C++中VTK9.3.0刻度標簽重疊的問題記錄

    這篇文章主要介紹了C++中VTK9.3.0刻度標簽重疊的問題,本文采用VTK9.3.0版本,其他版本如VKT8.0亦有同樣的問題,需要的朋友可以參考下
    2024-06-06

最新評論