標籤:編譯器 分配 out 函數代碼 一個 using 函數調用 虛函數表 虛函數
1.用類定義對象的時候,C++編譯器為每個對象編了一個一維的虛函數表(簡稱虛表)。這個虛函數表格儲存體了類中虛函數的函數入口地址;
2.用類定義對象的時候,C++編譯器還為每個對象分配了一個指向虛表開始地址的指標vptr;
3.當代碼運行時,C++編譯器首先判斷父類指標調用的函數是不是虛函數。
如果不是虛函數,則是普通函數。如果函數實參傳的是父類對象的地址(或父類對象的引用),則父類指標調用父類對象中的普通函數;如果實參傳的是子類對象的地址(或子類對象的引用),則父類指標調用子類中繼承自父類的普通函數。
如果是虛函數,則利用vpyr指標找到虛表,根據虛表找到虛函數的入口地址,直接執行函數代碼。這個過程C++編譯器不需判斷傳來的實參是父類對象的地址(或引用)還是子類對象的地址(或引用)
以如下的代碼為例:
1 #include<iostream> 2 using namespace std; 3 4 class Parent 5 { 6 public: 7 Parent(int _a):a(_a){} 8 ~Parent(){cout<<"執行Parent類解構函式"<<endl;} 9 virtual void print(){cout<<"列印Parent類 a:"<<a<<endl;}10 11 public:12 int a;13 };14 15 16 class Child:public Parent17 {18 public:19 Child(int _a,int _a_,int _b):Parent(_a),a(_a_),b(_b){}20 ~Child(){cout<<"執行Child類解構函式"<<endl;}21 void print(){cout<<"列印Child類 b:"<<b<<endl;}22 23 public:24 int a;25 int b;26 };27 28 29 void fun(Parent* p)30 {31 p->print();32 }33 34 35 36 int main()37 {38 Parent p(5);39 Child c(20,30,40);40 41 fun(&p);42 fun(&c);43 44 return 0;45 }
代碼的執行結果為:
列印Parent類 a:5
列印Child類 b:40
執行Child類解構函式
執行Parent類解構函式
執行Parent類解構函式
分析:代碼中的fun()函數調用的print()函數是虛函數,則走的是vptr-->虛表-->虛函數代碼這條路線
C++多態的實現機制