91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

C++純虛函數與抽象類是什么

發布時間:2020-08-14 13:54:28 來源:億速云 閱讀:203 作者:小新 欄目:開發技術

C++純虛函數與抽象類是什么?這個問題可能是我們日常學習或工作經常見到的。希望通過這個問題能讓你收獲頗深。下面是小編給大家帶來的參考內容,讓我們一起來看看吧!

1.虛函數

1.1虛函數簡介

虛函數可以毫不夸張的說是C++最重要的特性之一,我們先來看一看虛函數的概念。

在基類的定義中,定義虛函數的一般形式為:

virtual 函數返回值類型 虛函數名(形參表)
{
 函數體
}

為什么說虛函數是C++最重要的特性之一呢,因為虛函數承載著C++中動態聯編的作用,也即多態,可以讓程序在運行時選擇合適的成員函數。虛函數必須是類的非靜態成員函數(且非構造函數),其訪問權限是public。那么:
 (1)為什么類的靜態成員函數不能為虛函數?
 如果定義為虛函數,那么它就是動態綁定的,也就是在派生類中可以被覆蓋的,這與靜態成員函數的定義(在內存中只有一份拷貝,通過類名或對象引用訪問靜態成員)本身就是相矛盾的。

(2)為什么構造函數不能為虛函數?
 因為如果構造函數為虛函數的話,它將在執行期間被構造,而執行期則需要對象已經建立,構造函數所完成的工作就是為了建立合適的對象,因此在沒有構建好的對象上不可能執行多態(虛函數的目的就在于實現多態性)的工作。在繼承體系中,構造的順序就是從基類到派生類,其目的就在于確保對象能夠成功地構建。構造函數同時承擔著虛函數表的建立,如果它本身都是虛函數的話,又如何確保虛函數表的成功構建呢?

1.2虛析構函數

在類的繼承中,基類的析構函數一般都是虛函數。當基類中有虛函數的時候,析構函數也要定義為虛析構函數。如果不定義虛析構函數,當刪除一個指向派生類對象的指針時,會調用基類的析構函數,派生類的析構函數未被調用,造成內存泄露。

虛析構函數工作的方式是:最底層的派生類的析構函數最先被調用,然后各個基類的析構函數被調用。這樣,當刪除指向派生類的指針時,就會首先調用派生類的析構函數,不會有內存泄露的問題了。

一般情況下,如果類中沒有虛函數,就不用去聲明虛析構函數。當且僅當類里包含至少一個虛函數的時候才去聲明虛析構函數。只有當一個類被用來作為基類的時候,才有必要將析構函數寫成虛函數。

1.3虛函數的實現——虛函數表

虛函數是通過一張虛函數表來實現的,簡稱V-Table。類的虛函數表是一塊連續的內存,每個內存單元中記錄一個JMP指令的地址。編譯器會為每個有虛函數的類創建一個虛函數表,該虛函數表將被該類的所有對象共享,類的每個虛函數成員占據虛函數表中的一行。

在這個表中,存放的是一個類的虛函數的地址。這張表解決了繼承、覆蓋的問題,保證使用指向子類對象實體的基類指針或引用,能夠訪問到對象實際的虛函數。在有虛函數類的實例中,分配了指向這個表的指針的內存,所以,當用父類的指針來操作一個子類對象實體的時候,這張虛函數表就指明了實際所應該被調用的虛函數。

2.純虛函數與抽象類

既然有了虛函數,那為什么還需要有純虛函數呢?在Java編程語言中有接口的定義,在C++中雖然沒有接口關鍵字,但是純虛函數就完成了接口的功能。而且有時在編寫基類的時候,發生了如下情況:
 (1)功能不應由基類去完成;
 (2)還沒想好應該如何寫基類的這個函數;
 (3)有的時候基類本身不應被實例化。

這時就可以用到純虛函數了。下面我們通過一個例子比較虛函數和純虛函數的區別:

class Base 
{
public:
  //這是一個虛函數
  virtual void vir_func()
  {
   cout << "This is a virtual function of Base" << endl;
  }
  //這是一個純虛函數
  virtual void pure_vir_func() = 0;
};

由上可見,純虛函數在類中沒有定義函數體,并加上了“= 0”。而含有至少一個純虛函數的類被稱為抽象類。定義純虛函數和抽象類的目的在于,僅僅只定義派生類繼承的接口,而暫時無法提供一個合理的缺省實現。所以純虛函數的聲明就是在告訴子類的設計者,“你必須實現這個函數,但我不知道你會怎樣實現它”。

值得特別注意的是,由于抽象類至少有一個函數沒有實現,所以抽象類無法被實例化,否則編譯器會報錯。

下面看一下純虛函數與抽象類的實例。本實驗在GNU C++環境下進行。

#include <iostream>
using namespace std;

class Base
{
public:
  //這是一個虛函數
  virtual void vir_func()
  {
    cout << "This is a virtual function of Base" << endl;
  }

  //這是一個純虛函數
  virtual void pure_vir_func() =0;
};

class Derive : Base
{
public:
  void vir_func()
  {
    cout << "This is a virtual function of Derive" << endl;
  }

  void pure_vir_func()
  {
    cout << "This is a pure virtual function of Derive" << endl;
  }
};

int main()
{
  // Base b; //企圖實例化抽象類,編譯器報錯
  // b.vir_func();

  Derive d;
  d.vir_func();
  d.pure_vir_func();

  return 0;
}

輸出:

This is a virtual function of Derive
This is a pure virtual function of Derive

派生類Derive實現了基類Base類的虛函數和純虛函數,同時注意到,企圖去實例化抽象類,編譯器會報錯。

一般而言,純虛函數沒有函數體,但是也可以給出純虛函數的函數體,所以下面這樣的結構是可以通過編譯的:

class Base
{
public:
  //這是一個虛函數
  virtual void vir_func()
  {
   cout << "This is a virtual function of Base" << endl;
  }

  //這是一個純虛函數
  virtual void pure_vir_func() =0
  {
   cout << "This is a pure virtual function of Base" << endl;
  }
};

但這樣做并沒有什么意義,因為抽象類并不能實例化,不能調用該方法。

感謝各位的閱讀!看完上述內容,你們對C++純虛函數與抽象類是什么大概了解了嗎?希望文章內容對大家有所幫助。如果想了解更多相關文章內容,歡迎關注億速云行業資訊頻道。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

洪泽县| 台江县| 河南省| 安顺市| 正安县| 阆中市| 从化市| 九龙县| 宝丰县| 昌平区| 永兴县| 平远县| 抚宁县| 上栗县| 漳州市| 延安市| 时尚| 阜新市| 南平市| 绵阳市| 宾川县| 临漳县| 依安县| 八宿县| 大石桥市| 临湘市| 井研县| 庆元县| 油尖旺区| SHOW| 永善县| 华阴市| 华安县| 军事| 武冈市| 延安市| 泌阳县| 喀喇| 于都县| 西安市| 河曲县|