昨天看到一句話:對虛函數的調用不一定是動態聯編,我的映像中一直以為虛函數就是動態聯編的,所以記錄下來。
一、動態聯編是什么?
引自多態的概念:當不同的對象調用相同的名稱的成員函數時,可能引起不同的行為(執行不同的代碼),這種現象叫多態性。將函數調用鏈接相應函數體的代碼的過程稱為函數聯編。在C++中,分為靜態聯編和動態聯編。
靜態聯編:不同的類可以有同名的成員或函數,編譯器在編譯時對它們進行函數聯編,這種在編譯時刻進行的聯編稱為靜態聯編,也稱為編譯時多態性。函數重載屬於這種。
動態聯編:在程序運行時才能確定調用哪個函數,也稱為運行時多態性。在C++中,只有虛函數才可能是動態聯編的,可以通過定義類的虛函數和創建派生類,在派生類中重新實現虛函數,實現具有運行時的多態性。
二、如何調用靜態聯編的虛函數?(請參考 https://blog.csdn.net/chijianxingfeng/article/details/8870387 文章中的例子通俗易懂,文中稱為實調用)
1.例子:(派生類對象作為參數,傳給基類的形參)

#include <iostream> using namespace std; class A { public: virtual void show() { cout<<"in A::show()\n"; } }; class B:public A { public: void show() { cout<<"in B::show()\n"; } }; void func(A a) { a.show(); //a是A的一個實例,並不是指向類A對象的指針或引用,所以為實調用。 } int main() { B b; func(b); //調用類A的拷貝構造函數,產生一個A類對象作為a進入函數func()的函數體 //在函數體內,a是一個純粹的類A對象,與類型B毫無關系 return 0; }
輸出:
2.例子:(構造函數中調用虛函數)

#include <iostream> using namespace std; class A { public: virtual void show() { cout<<"in A::show()\n"; } A() { cout<<"A()\n"; show(); //調用虛函數 } }; class B:public A { public: void show() { cout<<"in B::show()\n"; } B() { cout<<"B()\n"; //show(); // } }; int main() { A a; B b; return 0; }
輸出: