繫結:確定程式中操作呼叫與執行該操作的**間的關係
靜態繫結:聯編工作出現在編譯階段,用物件名或者類名限定要呼叫的函式
動態繫結:聯編工作在程式執行中執行,在程式執行的時候在確定將要呼叫的函式
關於虛函式就是先簡單的知道是:要想要覆蓋class中的函式功能,就要必須要標記basic function
在想要覆蓋的函式前加上 virtual 就是在告訴編譯器,在此生成乙個vtable!
什麼是basic function?其實就是vtable機制!當編譯器發現在乙個類中有標記過的virtual,就會為它生成乙個「虛函式表」就是vtable,vtable其實就是乙個函式指標的陣列,每乙個虛函式都會占用乙個slot,就像是個對映!而乙個類就只有乙個vtable,但是派生類和繼承class有相同的函式陣列排列順序!而同名的虛函式被放在相同陣列的倆個位置上,
重要的是,編譯器會在每個例項內增加乙個虛函式指標vptr欄位,指向各自的vtable
因為派生class和繼承class有相同的vtable索引,但是各自的vptr又指向不同的vtable,因此既可以知道每次呼叫函式的時候,呼叫的是哪個了
有了多型,您可以有多個不同的類,都帶有同乙個名稱但具有不同實現的函式,函式的引數甚至可以是相同的。
class
entity};
class
player
:public entity
//建構函式
std::string getname()
};intmain()
列印出:entity cherno
但是目前為止,這段**都有垮掉的可能
class
entity};
class
player
:public entity
//建構函式
std::string getname()
};intmain()
列印出的是因為entity
cherno
entity
enitity *enitity = p;
想要的是將player的型別賦值給entity,但是entiy此時就發生了混亂,不知道該呼叫的是哪個的函式
或者也可以這樣表示:
class
entity};
class
player
:public entity
//建構函式
std::string getname()
};void
printname
(enitity* entity)
intmain()
但是列印出的只有倆個entity!所以想要覆蓋函式的話,則需要在基類中將基函式(basic function)標記為虛函式!
貼出完整**貼處完整**注意有個override,它只能是和virtual聯合一起來用的 ps:還可以來檢查虛函式的使用是否正確!
#include
#include
class
enitity};
class
player
:public enitity
std::string getname
() override };
//或者
void
printname
(enitity* entity)
intmain()
虛函式必須是非靜態的成員函式 詳見下面!
如果是使用物件名來訪問虛函式,則繫結在編譯過程中就可以進行(靜態繫結),無需在執行時進行動態繫結了;
約定俗成的是:虛函式一般不宣告為內斂,因為虛函式是需要動態繫結的,而內聯函式的處理是靜態的,所以虛函式一般不能以內聯函式處理!
虛指標,虛函式,虛函式表,純虛函式
虛指標 虛繼承 在使用多重繼承時,如存在 class a 有m a變數 class a1 virtual public a,m a1 class a2 virtual public a m a2 class b public a1,public a2 m b 時 存在以下記憶體儲存順序 虛指標 指向...
虛函式 純虛函式
一 定義.純虛函式是在基類中宣告的虛函式,它在基類中沒有定義,但要求任何派生類都要定義自己的實現方法。在基類中實現純虛函式的方法是在函式原型後加 0 virtual void funtion1 0 二 引入原因 1 為了方便使用多型特性,我們常常需要在基類中定義虛函式。2 在很多情況下,基類本身生成...
虛函式 純虛函式
虛函式的作用是允許在派生類中重新定義與基類同名的函式,並且可以通過基類指標引用來訪問基類和派生類中的同名函式。include using namespace std class student student類成員函式的實現 宣告抽象基類shape class shape virtual float...