最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

詳解C++純虛函數(shù)與抽象類

 更新時(shí)間:2020年08月13日 11:27:31   作者:Dabelv  
這篇文章主要介紹了C++純虛函數(shù)與抽象類的相關(guān)資料,幫助大家更好的理解和學(xué)習(xí)c++,感興趣的朋友可以了解下

1.虛函數(shù)

1.1虛函數(shù)簡介

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

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

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

為什么說虛函數(shù)是C++最重要的特性之一呢,因?yàn)樘摵瘮?shù)承載著C++中動(dòng)態(tài)聯(lián)編的作用,也即多態(tài),可以讓程序在運(yùn)行時(shí)選擇合適的成員函數(shù)。虛函數(shù)必須是類的非靜態(tài)成員函數(shù)(且非構(gòu)造函數(shù)),其訪問權(quán)限是public。那么:
 (1)為什么類的靜態(tài)成員函數(shù)不能為虛函數(shù)?
 如果定義為虛函數(shù),那么它就是動(dòng)態(tài)綁定的,也就是在派生類中可以被覆蓋的,這與靜態(tài)成員函數(shù)的定義(在內(nèi)存中只有一份拷貝,通過類名或?qū)ο笠迷L問靜態(tài)成員)本身就是相矛盾的。

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

1.2虛析構(gòu)函數(shù)

在類的繼承中,基類的析構(gòu)函數(shù)一般都是虛函數(shù)。當(dāng)基類中有虛函數(shù)的時(shí)候,析構(gòu)函數(shù)也要定義為虛析構(gòu)函數(shù)。如果不定義虛析構(gòu)函數(shù),當(dāng)刪除一個(gè)指向派生類對(duì)象的指針時(shí),會(huì)調(diào)用基類的析構(gòu)函數(shù),派生類的析構(gòu)函數(shù)未被調(diào)用,造成內(nèi)存泄露。

虛析構(gòu)函數(shù)工作的方式是:最底層的派生類的析構(gòu)函數(shù)最先被調(diào)用,然后各個(gè)基類的析構(gòu)函數(shù)被調(diào)用。這樣,當(dāng)刪除指向派生類的指針時(shí),就會(huì)首先調(diào)用派生類的析構(gòu)函數(shù),不會(huì)有內(nèi)存泄露的問題了。

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

1.3虛函數(shù)的實(shí)現(xiàn)——虛函數(shù)表

虛函數(shù)是通過一張?zhí)摵瘮?shù)表來實(shí)現(xiàn)的,簡稱V-Table。類的虛函數(shù)表是一塊連續(xù)的內(nèi)存,每個(gè)內(nèi)存單元中記錄一個(gè)JMP指令的地址。編譯器會(huì)為每個(gè)有虛函數(shù)的類創(chuàng)建一個(gè)虛函數(shù)表,該虛函數(shù)表將被該類的所有對(duì)象共享,類的每個(gè)虛函數(shù)成員占據(jù)虛函數(shù)表中的一行。

在這個(gè)表中,存放的是一個(gè)類的虛函數(shù)的地址。這張表解決了繼承、覆蓋的問題,保證使用指向子類對(duì)象實(shí)體的基類指針或引用,能夠訪問到對(duì)象實(shí)際的虛函數(shù)。在有虛函數(shù)類的實(shí)例中,分配了指向這個(gè)表的指針的內(nèi)存,所以,當(dāng)用父類的指針來操作一個(gè)子類對(duì)象實(shí)體的時(shí)候,這張?zhí)摵瘮?shù)表就指明了實(shí)際所應(yīng)該被調(diào)用的虛函數(shù)。

2.純虛函數(shù)與抽象類

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

這時(shí)就可以用到純虛函數(shù)了。下面我們通過一個(gè)例子比較虛函數(shù)和純虛函數(shù)的區(qū)別:

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

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

值得特別注意的是,由于抽象類至少有一個(gè)函數(shù)沒有實(shí)現(xiàn),所以抽象類無法被實(shí)例化,否則編譯器會(huì)報(bào)錯(cuò)。

下面看一下純虛函數(shù)與抽象類的實(shí)例。本實(shí)驗(yàn)在GNU C++環(huán)境下進(jìn)行。

#include <iostream>
using namespace std;

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

  //這是一個(gè)純虛函數(shù)
  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; //企圖實(shí)例化抽象類,編譯器報(bào)錯(cuò)
  // 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實(shí)現(xiàn)了基類Base類的虛函數(shù)和純虛函數(shù),同時(shí)注意到,企圖去實(shí)例化抽象類,編譯器會(huì)報(bào)錯(cuò)。

一般而言,純虛函數(shù)沒有函數(shù)體,但是也可以給出純虛函數(shù)的函數(shù)體,所以下面這樣的結(jié)構(gòu)是可以通過編譯的:

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

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

但這樣做并沒有什么意義,因?yàn)槌橄箢惒⒉荒軐?shí)例化,不能調(diào)用該方法。

以上就是詳解C++純虛函數(shù)與抽象類的詳細(xì)內(nèi)容,更多關(guān)于C++純虛函數(shù)與抽象類的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • C語言實(shí)現(xiàn)洗牌發(fā)牌小程序

    C語言實(shí)現(xiàn)洗牌發(fā)牌小程序

    這篇文章主要介紹了C語言實(shí)現(xiàn)洗牌發(fā)牌小程序,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-04-04
  • 循環(huán)隊(duì)列詳解及隊(duì)列的順序表示和實(shí)現(xiàn)

    循環(huán)隊(duì)列詳解及隊(duì)列的順序表示和實(shí)現(xiàn)

    這篇文章主要介紹了循環(huán)隊(duì)列詳解及隊(duì)列的順序表示和實(shí)現(xiàn)的相關(guān)資料,需要的朋友可以參考下
    2016-12-12
  • 劍指offer之C語言不修改數(shù)組找出重復(fù)的數(shù)字

    劍指offer之C語言不修改數(shù)組找出重復(fù)的數(shù)字

    今天小編就為大家分享一篇關(guān)于劍指offer之C語言不修改數(shù)組找出重復(fù)的數(shù)字,小編覺得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來看看吧
    2019-02-02
  • C語言實(shí)現(xiàn)快速排序

    C語言實(shí)現(xiàn)快速排序

    快速排序不一定是穩(wěn)定排序,這篇文章主要為大家詳細(xì)介紹了C語言實(shí)現(xiàn)快速排序算法,具有一定的參考價(jià)值,感興趣的同學(xué)可以借鑒閱讀
    2023-03-03
  • C語言中結(jié)構(gòu)體的內(nèi)存對(duì)齊規(guī)則講解

    C語言中結(jié)構(gòu)體的內(nèi)存對(duì)齊規(guī)則講解

    C 數(shù)組允許定義可存儲(chǔ)相同類型數(shù)據(jù)項(xiàng)的變量,結(jié)構(gòu)是 C 編程中另一種用戶自定義的可用的數(shù)據(jù)類型,它允許你存儲(chǔ)不同類型的數(shù)據(jù)項(xiàng),本篇讓我們來了解C 的結(jié)構(gòu)體內(nèi)存對(duì)齊
    2022-05-05
  • C++實(shí)現(xiàn)馬踏棋盤(騎士周游)

    C++實(shí)現(xiàn)馬踏棋盤(騎士周游)

    這篇文章主要為大家詳細(xì)介紹了C++實(shí)現(xiàn)馬踏棋盤,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-02-02
  • VisualStudio2022不支持.NET Framework 4.0項(xiàng)目解決辦法

    VisualStudio2022不支持.NET Framework 4.0項(xiàng)目解決辦法

    本文主要介紹了VisualStudio2022不支持.NET Framework 4.0項(xiàng)目解決辦法,文中通過圖文的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-09-09
  • OpenCV畫任意圓弧曲線

    OpenCV畫任意圓弧曲線

    這篇文章主要為大家詳細(xì)介紹了OpenCV畫任意圓弧曲線,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-01-01
  • C語言結(jié)構(gòu)體成員賦值的深拷貝與淺拷貝詳解

    C語言結(jié)構(gòu)體成員賦值的深拷貝與淺拷貝詳解

    C語言中的淺拷貝是指在拷貝過程中,對(duì)于指針型成員變量只拷貝指針本身,而不拷貝指針?biāo)赶虻哪繕?biāo),它按字節(jié)復(fù)制的。深拷貝除了拷貝其成員本身的值之外,還拷貝成員指向的動(dòng)態(tài)內(nèi)存區(qū)域內(nèi)容。本文將通過示例和大家詳細(xì)說說C語言的深拷貝與淺拷貝,希望對(duì)你有所幫助
    2022-09-09
  • C++空類詳解

    C++空類詳解

    以下是對(duì)C++中的空類進(jìn)行了詳細(xì)的介紹,需要的朋友可以過來參考下
    2013-09-09

最新評(píng)論

长汀县| 闽侯县| 错那县| 榆中县| 申扎县| 合川市| 汕头市| 凤山市| 定结县| 赤壁市| 松原市| 乡宁县| 镇巴县| 随州市| 辽中县| 山阳县| 阳谷县| 浑源县| 鄂托克前旗| 武隆县| 湖北省| 寿阳县| 宁夏| 澜沧| 四会市| 廊坊市| 洛扎县| 卢湾区| 淳化县| 土默特右旗| 清苑县| 瑞安市| 县级市| 昆山市| 南澳县| 丹凤县| 苏尼特左旗| 四川省| 临夏市| 安国市| 尚志市|