[英]Pointer-to-member-function performs virtual dispatch?
我嘗試執行以下代碼。
#include <iostream>
class Base
{
public:
virtual void func()
{
std::cout<<"Base called"<<std::endl;
}
};
class Derived: public Base
{
public:
virtual void func() override
{
std::cout<<"Derived called"<<std::endl;
}
};
int main()
{
void (Base::*func_ptr)()=&Base::func; //Yes, the syntax is very beautiful.
Base* bptr=new Derived();
(bptr->*func_ptr)();
}
我的預期輸出是Base called
。 然而,相反,輸出是
Derived called
這讓我感到驚訝,因為我認為func_ptr
應該只能看到Base
成員(因為我認為func_ptr
不是通過_vptr
訪問成員函數,而是通過函數地址本身。
我想知道,在這種情況下如何進行虛擬分派(如何訪問虛擬表),以及在 C++ 標准中定義此行為的位置(我找不到任何東西)?
參考[expr.call] ,特別是這里
[如果選擇的函數是虛擬的],它在對象表達式的動態類型中的最終覆蓋被調用; 這樣的調用稱為虛函數調用
無論是通過指針調用函數還是通過類成員訪問調用函數都是一樣的( ref ); 為虛函數調用的實際函數最終取決於它被調用的對象的實際類型。
[class.virtual]下標准中的一些(非規范性)注釋大致相同:
[注3:虛函數調用的解釋取決於調用它的對象的類型(動態類型)
[注 4:[...] 虛擬函數調用依賴於特定對象來確定要調用哪個函數。
如果你想知道虛函數調度是如何發生的,你需要尋找一個具體的實現,因為如何不是標准化的。
(我真的很喜歡這篇文章虛擬表的基本概覽,它展示了一種可以使用 C 實現它的可能方法)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.