中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

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

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

C++中的虛成員函數和動態聯編是什么

發布時間:2020-07-01 18:15:32 來源:億速云 閱讀:147 作者:元一 欄目:編程語言

C++中的虛成員函數和動態聯編是什么?很多新手對此不是很清楚,為了幫助大家解決這個難題,下面小編將為大家詳細講解,有這方面需求的人可以來學習下,希望你能有所收獲。

虛成員函數:

虛函數允許派生類取代基類所提供的實現。編譯器確保當對象為派生類時,取代者(譯注:即派生類的實現)總是被調用,即使對象是使用基類指針訪問而不是派生類的指針。這樣就允許基類的算法被派生類取代,即使用戶不知道派生類的細節。

派生類可以完全地取代基類成員函數(覆蓋(override)),也可以部分地取代基類成員函數(增大(augment))。如果愿意的話,后者由派生類成員函數調用基類成員函數來完成。
在構造函數訪問順序中,一般來說是先訪問父類的構造函數再訪問子類的構造函數,析構函數則是先訪問子類的析構函數,再訪問父類的析構函數。

動態聯編:

編譯程序在編譯階段并不能確切知道將要調用的函數,只有在程序運行時才能確定將要調用的函數,為此要確切知道該調用的函數,要求聯編工作要在程序運行時進行,這種在程序運行時進行聯編工作被稱為動態聯編。動態聯編又稱動態關聯。

編譯器對非虛方法使用靜態聯編(編譯時匹配),對虛方法使用動態聯編(運行時匹配)。

  • 未使用虛方法時,指針類型在編譯時已知,因此編譯器在編譯時,可以將成員方法關聯到相應的類,這被稱為靜態聯編;
  • 使用虛方法時,通常只有在運行程序時才能確定對象類型,所以編譯器生成的代碼在程序執行時將成員函數關聯到相應的類,這被稱為動態聯編。

  靜態聯編比動態聯編效率高。

  虛函數的工作原理。

  虛函數。

  重新定義成員函數(改變函數特征標)。

  重新定義重載的成員函數。

 效率

 為使程序能夠在運行階段進行決策,必須采取一些方法來跟蹤基類指針或引用指向的對象類型,這增加了額外的處理開銷。因此下列情況更適合靜態聯編:

  • 類不會用作基類
  • 派生類不重新定義基類的任何方法

 因此靜態聯編被設置為C++的默認選擇。

 如果要在派生類中重新定義基類的方法,則將它設置為虛方法;否則設置為非虛方法。

 虛函數的工作原理

 編譯器處理虛函數的方法是:給每個對象添加一個隱藏成員。隱藏成員中保存了一個指向·函數地址·數組的指針。這種數組被稱為虛函數表(vtbl),表中存儲了為類對象進行聲明的虛函數的地址。

 派生類對象將包含一個指向獨立地址表的指針(即新創建一個表)。(增加內存開銷)

 調用虛函數時,程序將查看存儲在對象中的vtbl地址,然后轉向相應的函數地址表并在表中查找地址。(影響執行速度)

 總之,使用虛函數將在內存和執行速度上有一定的成本;即使非函數的效率比虛函數稍高,卻不具備動態聯編功能。

 構造函數不能是虛函數。

 析構函數應當是虛函數,除非類不用做基類。

 友元函數不能是虛函數,因為友元不是類成員,而只有成員才可以是虛函數。

 如果派生類沒有重新定義函數,將使用該函數的基類版本(繼承它)。如果派生類位于派生鏈中,則將使用最新的虛函數版本(指針或引用調用),基類版本被隱藏的情況除外。

重新定義將隱藏基類方法:

class Dwelling
{public:    virtual void showperks(int a) const;
    ...
};class Hovel : public Dwelling
{public:    virtual void showperks() const;
    ...
}

 在派生類中重新定義函數(改變了參數特征標),將隱藏同名的基類方法,而不是重載基類方法。

Hovel trump;
trump.showperks();    // validtrump.showperks(5);    // invalid

 如果重新定義繼承的方法,應確保與原來的原型完全相同。如果返回類型為基類引用或指針,則可以修改為指向派生類的引用或指針(返回類型協變:即允許返回類型隨類類型的變化而變化)。

 如果基類聲明被重載了,則應在派生類中重新定義所有的基類版本;如果只定義了一個版本,則其它版本將被隱藏,派生類對象將無法使用它們。

class Dwelling
{public:    virtual void showperks(int a) const;    virtual void showperks(double x) const;    virtual void showperks() const;
    ...
};class Hovel : public Dwelling
{    virtual void showperks(int a) const;    virtual void showperks(double x) const;    virtual void showperks() const;
    ...
};

 如果不需要修改,則新定義可只調用基類版本:

  void Hovel::showperks()const {Dwelling::showperks();}  

看完上述內容是否對您有幫助呢?如果還想對相關知識有進一步的了解或閱讀更多相關文章,請關注億速云行業資訊頻道,感謝您對億速云的支持。

向AI問一下細節

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

AI

思茅市| 页游| 彰武县| 南华县| 阆中市| 彭州市| 克拉玛依市| 通化县| 武山县| 宁陵县| 晋城| 犍为县| 平和县| 油尖旺区| 龙泉市| 宣威市| 沁水县| 增城市| 图木舒克市| 新兴县| 临潭县| 通州区| 阜新市| 方正县| 富锦市| 鄂伦春自治旗| 合山市| 达孜县| 会泽县| 凤冈县| 珠海市| 宁都县| 海林市| 威信县| 信阳市| 车致| 马尔康县| 巢湖市| 临泽县| 铁岭县| 定安县|