C++中的虛擬函式及其實現方式
阿新 • • 發佈:2019-02-01
首先看程式碼,不採用虛擬函式的情況
// ConsoleApplication1.cpp : 定義控制檯應用程式的入口點。 // #include "stdafx.h" #include <iostream> using namespace std; class A { private: int m_kk; public: A() { m_kk = 100; } void print() { cout << "this is A" << endl; cout << m_kk << endl; } }; class B :public A { public: void print(){ cout << "this is B" << endl; } }; int main() { A a; B b; A* pa = &a; A* pb = &b; pa->print(); pb->print(); system("pause"); return 0; }
上述的兩次輸出均為“this is A 100”。證明在不採用虛擬函式的基礎上,用父類的指標指向子類,是指向子類中父類的一部分。其行為和父類相同。
下面是採用虛擬函式的情況
// ConsoleApplication1.cpp : 定義控制檯應用程式的入口點。 // #include "stdafx.h" #include <iostream> using namespace std; class A { private: int m_kk; public: A() { m_kk = 100; } virtual void print() { cout << "this is A" << endl; cout << m_kk << endl; } }; class B :public A { public: virtual void print(){ cout << "this is B" << endl; } }; int main() { A a; B b; A* pa = &a; A* pb = &b; pa->print(); pb->print(); system("pause"); return 0; }
輸出為this is A 100 this is B.證明父類指標指向子類物件時,呼叫虛擬函式是呼叫子類中的實現。下面對虛擬函式的實現機理做闡釋:
如果一個類中存在虛擬函式,編譯器會為該類建立一個虛擬函式地址表(vtbl),儲存自己類中虛擬函式的地址。併為改建建立一個指標(vptr),指向這個表。每個類的物件都會有一個vptr,該類的所有物件公用一個vtbl。
當執行上面的pb->print()時,系統會先獲取pb的vtbr,得到vtbl後進行分析後得出結果。