31.C++-虛函數之構造函數與析構函數分析


1.構造函數不能為虛函數

當我們將構造函數定義為虛函數時,會直接報錯:

 

 

首先回憶下以前學的virtual虛函數概念:

  • 如果類定義了虛函數,創建對象時,則會分配內存空間,並且為該父類以及其所有子類的內存空間上額外分配一個虛函數表.
  • 虛函數表的作用在於,存儲每個類的相同的虛函數名,然后每一次虛函數調用,都會去虛函數表查找地址

分析:

假如構造函數是虛函數的話,由於對象開始還未分配內存空間,所以根本就無法找到虛函數表,從而構造函數也無法被調用.所以構造函數是不能成為虛函數.

 

2. 析構函數可以為虛函數

首先回憶下析構函數:

當某個內對象被注銷時,編譯器會自動順序調用該類以及其父類的析構函數,而不會調用派生類的析構函數.

虛析構函數的好處

假如我們通過派生類生成基類對象時,如果析構函數是虛函數,則我們釋放其基類對象時,能使整個類(包括派生類)對象完全釋放,如果析構函數只是普通函數,則不能析構完全.

 

分析:

所以當我們在用多態的時候(通過基類來調用派生類成員函數),析構函數最好為虛函數

 

示例如下:

#include <iostream>
using namespace std;

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

  virtual void func()                         //虛函數成員
  {
      cout<<"ClassBase: func()"<<endl;
  }
};

class ClassDerived : public ClassBase
{
public:
  ClassDerived(){};
  ~ClassDerived()
  {
      cout<<"~ClassDerived()"<<endl;
  }
  void func()                    //虛函數成員
  {
      cout<<"ClassDerived: func()"<<endl;
  }
};

 int main()
{
   ClassBase *p = new  ClassDerived;

   p->func();                   //通過多態來調用派生類虛函數

   delete p;

   return 0;
}

打印如下:

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM