Cpp 对象模型探索 / 虚函数的调用方式
生活随笔
收集整理的這篇文章主要介紹了
Cpp 对象模型探索 / 虚函数的调用方式
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
虛函數有兩種調用方式:
- 方案1,直接使用函數地址調用。
- 方案2,通過對象的虛函數表指針找到虛函數表,從而得到函數地址,完成調用。
應用場景主要有如下三種情況:
(1)若是直接調用,則走方案 2 路線。
(2)若是使用 類名::虛函數,則走方案 1 路線。? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
栗子:
class CBase { public:virtual void func() { std::cout << "CBase::func()" << std::endl; } };class CA : public CBase { public:void func() { std::cout << "CA::func()" << std::endl; }void func_1() { CBase::func(); }void func_2() { func(); } };(1)當執行如下代碼時,
CA A; A.func(); CBase Base; Base.func();結果為
CA::func() CBase::func()轉成匯編,
005D29F6 call CA::func (05D1325h) 005D29FE call CBase::CBase (05D11F9h)?可以發現,編譯器采用的是直接調用的方式,與場景1相對應。
(2)當執行如下代碼時,
CBase* pbase = new CA; pbase->func();結果為
CA::func()轉成匯編,?
27: pbase->func(); 005D2A8D mov eax,dword ptr [pbase] 005D2A90 mov edx,dword ptr [eax] 005D2A92 mov esi,esp 005D2A94 mov ecx,dword ptr [pbase] 005D2A97 mov eax,dword ptr [edx] 005D2A99 call eax 005D2A9B cmp esi,esp 005D2A9D call __RTC_CheckEsp (05D12F3h)?執行的方案是通過對象的虛函數表指針找到虛函數表,從而得到函數地址,完成調用。與場景2相對應。
(3)執行如下代碼,
A.func_1(); A.func_2();結果為
CBase::func() CA::func()?轉成匯編,
17: CBase::func(); 0071284D mov ecx,dword ptr [this] 00712850 call CBase::func (071120Dh)21: func(); 007128AD mov eax,dword ptr [this] 007128B0 mov edx,dword ptr [eax] 007128B2 mov esi,esp 007128B4 mov ecx,dword ptr [this] 007128B7 mov eax,dword ptr [edx] 007128B9 call eax 007128BB cmp esi,esp 007128BD call __RTC_CheckEsp (07112F3h)可以發現,前者是直接調用的方式 ,后者是通過虛函數表才找到的虛函數的地址。與場景3相對應。
?
?
(SAW:Game Over!)
總結
以上是生活随笔為你收集整理的Cpp 对象模型探索 / 虚函数的调用方式的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Cpp 对象模型探索 / 类普通成员函数
- 下一篇: Cpp 对象模型探索 / 类静态成员函数