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

詳解C++中虛析構函數的作用及其原理分析

 更新時間:2019年04月08日 10:38:53   作者:Stoneplay26  
這篇文章主要介紹了C++中虛析構函數的作用及其原理分析,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧

C++中的虛析構函數到底什么時候有用的,什么作用呢。

一.虛析構函數的作用

總的來說虛析構函數是為了避免內存泄露,而且是當子類中會有指針成員變量時才會使用得到的。也就說虛析構函數使得在刪除指向子類對象的基類指針時可以調用子類的析構函數達到釋放子類中堆內存的目的,而防止內存泄露的.

我們知道,用C++開發(fā)的時候,用來做基類的類的析構函數一般都是虛函數??墒?,為什么要這樣做呢?下面用一個小例子來說明:

#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析構函數前的virtual去掉,那輸出結果就是下面的樣子了:

沒有調動子類的析構函數

也就是說,類ClxDerived的析構函數根本沒有被調用!一般情況下類的析構函數里面都是釋放內存資源,而析構函數不被調用的話就會造成內存泄漏。我想所有的C++程序員都知道這樣的危險性。當然,如果在析構函數中做了其他工作的話,那你的所有努力也都是白費力氣。

所以,文章開頭的那個問題的答案就是--這樣做是為了當用一個基類的指針刪除一個派生類的對象時,派生類的析構函數會被調用。

當然,并不是要把所有類的析構函數都寫成虛函數。因為當類里面有虛函數的時候,編譯器會給類添加一個虛函數表,里面來存放虛函數指針,這樣就會增加類的存儲空間。所以,只有當一個類被用來作為基類的時候,才把析構函數寫成虛函數。

總結一下虛析構函數的作用:

(1)如果父類的析構函數不加virtual關鍵字
當父類的析構函數不聲明成虛析構函數的時候,當子類繼承父類,父類的指針指向子類時,delete掉父類的指針,只調動父類的析構函數,而不調動子類的析構函數。

(2)如果父類的析構函數加virtual關鍵字
當父類的析構函數聲明成虛析構函數的時候,當子類繼承父類,父類的指針指向子類時,delete掉父類的指針,先調動子類的析構函數,再調動父類的析構函數。

二.虛析構函數的原理分析

#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調試你會發(fā)現,

(1)先調用父類的構造函數,再調用子類的構造函數,

這里有一個問題:父類的構造函數/析構函數與子類的構造函數/析構函數會形成多態(tài),但是當父類的構造函數/析構函數即使被聲明virtual,子類的構造/析構方法仍無法覆蓋父類的構造方法和析構方法。這是由于父類的構造函數和析構函數是子類無法繼承的,也就是說每一個類都有自己獨有的構造函數和析構函數。

(2)而由于父類的析構函數為虛函數,所以子類會在所有屬性的前面形成虛表,而虛表內部存儲的就是父類的虛函數

即使子類也有虛函數,但是由于是單繼承,所以也只有一張?zhí)摫?,這在上一篇博客多態(tài)中講到過。
執(zhí)行 Base *b = new Der;之后b的最終形態(tài)

(3)當delete父類的指針時,由于子類的析構函數與父類的析構函數構成多態(tài),所以得先調動子類的析構函數;之所以再調動父類的析構函數,是因為delete的機制所引起的,delete 父類指針所指的空間,要調用父類的析構函數。
所以結果就是這樣

以上所述是小編給大家介紹的C++中虛析構函數的作用及其原理分析詳解整合,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復大家的。在此也非常感謝大家對腳本之家網站的支持!

相關文章

  • C語言程序環(huán)境中的預處理詳解

    C語言程序環(huán)境中的預處理詳解

    這篇文章主要為大家詳細介紹了C語言程序環(huán)境中的預處理,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2022-02-02
  • C C++ 算法實例大全

    C C++ 算法實例大全

    這篇文章主要介紹了C C++ 算法實例大全,里面大量的實例介紹,學習c語言的朋友可以收藏
    2016-12-12
  • C++超細致講解隊列queue的使用

    C++超細致講解隊列queue的使用

    隊列先進先出,即只能在容器的末尾添加新元素,只能從頭部移除元素,下面這篇文章主要給大家介紹了關于C++中隊列queue用法的相關資料,文中通過示例代碼介紹的非常詳細,需要的朋友可以參考下
    2022-05-05
  • C語言實現小學生隨機出題測試計分

    C語言實現小學生隨機出題測試計分

    這篇文章主要為大家詳細介紹了C語言實現小學生隨機出題測試計分,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-03-03
  • C語言編程時常犯十八個錯誤小結

    C語言編程時常犯十八個錯誤小結

    C語言的最大特點是:功能強、使用方便靈活。C編譯的程序對語法檢查并不象其它高級語言那么嚴格,這就給編程人員留下“靈活的余地”,但還是由于這個靈活給程序的調試帶來了許多不便,尤其對初學C語言的人來說,經常會出一些連自己都不知道錯在哪里的錯誤
    2013-07-07
  • 深入理解c++20 concepts

    深入理解c++20 concepts

    本文主要介紹了深入理解c++20 concepts,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2023-06-06
  • 基于Matlab繪制超絢麗的煙花的過程詳解

    基于Matlab繪制超絢麗的煙花的過程詳解

    這篇文章主要為大家介紹了如何利用Matlab繪制超絢麗的煙花,文中的示例代碼講解詳細,對我們學習Matlab有一定幫助,需要的可以參考一下
    2022-02-02
  • C++?TCP網絡編程詳細講解

    C++?TCP網絡編程詳細講解

    TCP/IP是一種面向連接的、可靠的、基于字節(jié)流的傳輸層通信協(xié)議,它會保證數據不丟包、不亂序。TCP全名是Transmission?Control?Protocol,它是位于網絡OSI模型中的第四層
    2022-09-09
  • C++實現LeetCode(198.打家劫舍)

    C++實現LeetCode(198.打家劫舍)

    這篇文章主要介紹了C++實現LeetCode(198.打家劫舍),本篇文章通過簡要的案例,講解了該項技術的了解與使用,以下就是詳細內容,需要的朋友可以參考下
    2021-08-08
  • C&C++設計風格選擇 命名規(guī)范

    C&C++設計風格選擇 命名規(guī)范

    本文難免帶有主觀選擇傾向,但是會盡量保持客觀的態(tài)度歸納幾種主流的命名風格,僅供參考
    2018-04-04

最新評論