虛函式的作用:實現類的多型性
用法:在基類定義虛函式,子類可以重寫該函式
在派生類中對基類定義的虛函式進行重寫時,需要在派生類中宣告該方法為虛方法。
如果使用了virtual關鍵字,程式將根據引用或指標指向的對 象 類 型來選擇方法,否則使用引用型別或指標型別來選擇方法
eg:
#includeusing namespace std;
class a
~a() = default;
virtual void func1()
virtual void func2()
virtual void func2(int val)
};class b: public a ;
// virtual void func1()
virtual void func2(int val)override
};int main()
簡而言之,如果指標所指向的派生類物件中有該方法就呼叫該方法,否則就呼叫基類中的方法
override保留字:override保留字表示當前函式重寫了基類的虛函式。
目的:
1.在函式比較多的情況下可以提示讀者某個函式重寫了基類虛函式(表示這個虛函式是從基類繼承,不是派生類自己定義的);
2.強制編譯器檢查某個函式是否重寫基類虛函式,如果沒有則報錯。
注意:override只是c++保留字,不是關鍵字,這意味著只有在正確的使用位置,oerride才啟「關鍵字」的作用,其他地方可以作為標誌符(如:int override;是合法的)。
相關:override還有乙個姊妹保留字final。
實現原理:虛表指標+虛表函式
編譯器處理虛函式的方法是:為每個類物件新增乙個隱藏成員,隱藏成員中儲存了乙個指向函式位址陣列的指標,稱為虛表指標(vptr),這種陣列稱為虛函式表(virtual function table, vtbl),即,每個類使用乙個虛函式表,每個類物件用乙個虛表指標。(這樣做會花費格外的儲存空間)
基類物件包含乙個虛表指標,指向基類中所有虛函式的位址表。派生類物件也將包含乙個虛表指標,指向派生類虛函式表。看下面兩種情況:
如果派生類重寫了基類的虛方法,該派生類虛函式表將儲存重寫的虛函式的位址,而不是基類的虛函式位址。
如果基類中的虛方法沒有在派生類中重寫,那麼派生類將繼承基類中的虛方法,而且派生類中虛函式表將儲存基類中未被重寫的虛函式的位址。注意,如果派生類中定義了新的虛方法,則該虛函式的位址也將被新增到派生類虛函式表中。
總結前面的內容
(1) 基類方法中宣告了方法為虛後,該方法在基類派生類中是虛的。
(2) 若使用指向物件的引用或指標呼叫虛方法,程式將根據物件型別來呼叫方法,而不是指標的型別。
(3)如果定義的類被用作基類,則應將那些要在派生類中重新定義的類方法宣告為虛。
建構函式不能為虛函式。
基類的析構函式應該為虛函式。
友元函式不能為虛,因為友元函式不是類成員,只有類成員才能是虛函式。
如果派生類沒有重定義函式,則會使用基類版本。
重新定義繼承的方法若和基類的方法不同(協變除外),會將基類方法隱藏;如果基類宣告方法被過載,則派生類也需要對過載的方法重新定義,否則呼叫的還是基類的方法。
將可能會被繼承的父類的析構函式設定為虛函式,可以保證當我們new乙個子類,然後使用基類指標指向該子類物件,釋放基類指標時可以釋放掉子類的空間,防止記憶體洩漏。
c++預設的析構函式不是虛函式是因為虛函式需要額外的虛函式表和虛表指標,占用額外的記憶體。而對於不會被繼承的類來說,其析構函式如果是虛函式,就會浪費記憶體。因此c++預設的析構函式不是虛函式,而是只有當需要當作父類時,設定為虛函式。
靜態函式在編譯的時候就已經確定執行時機,虛函式在執行的時候動態繫結。虛函式因為用了虛函式表機制,呼叫的時候會增加一次記憶體開銷
C 中的虛函式 純虛函式
c 最重要的特性就是多型,而多型,就主要通過虛函式實現的。具體的實現過程是 基類中的函式定義為虛函式,派生類發生覆蓋 即函式名稱 引數列表 返回值型別完全相同 的情況下,派生類中的函式也會自動變成虛函式,不論加不加virtual關鍵字。此時,基類與子類物件中都會存在一張虛函式表 因為含有虛函式 具體...
C 中的虛函式
c 中的虛函式 virtual function 1.簡介 虛函式是c 中用於實現多型 polymorphism 的機制。核心理念就是通過基類訪問派生類定義的函式。假設我們有下面的類層次 class a class b public a 那麼,在使用的時候,我們可以 a a new b a foo ...
C 中的虛函式
c 中的虛函式 一 雖然很難找到一本不討論多型性的c 書籍或雜誌,但是,大多數這類討論使多型性和c 虛函式的使用看起來很難。我打算在這篇文章中通過從幾個方面和結合一些例子使讀者理解在c 中的虛函式實現技術。說明一點,寫這篇文章只是想和大家交流學習經驗因為本人學識淺薄,難免有一些錯誤和不足,希望大家批...