[英]Unexpected Output…how function binding happens in virtual table
class Base
{
public:
int a;
virtual void fun1()
{
cout<<"Hello Base"<<endl;
}
void fun2()
{
fun1();
}
};
class Derived: public Base
{
int a;
void fun1()
{
cout<<"Hello Derived"<<endl;
}
};
int main()
{
Base * B = new Derived;
B->fun2();
return 1;
}
請幫助我理解為什么輸出是Hello Derived。如何進行此函數綁定。如何為Base和派生類創建虛擬表條目。
偽代碼如下所示:
#include <iostream>
class Base{
protected:
void **vt_ptr;
public:
int a;
//Executed prior to base member initialization
//and reexecuted prior to Base destructor call
void set_dynamic_type(){
vt_ptr = Base::vtable;
}
/*virtual*/
void fun1(){
reinterpret_cast<void(*)(Base&)>(vt_ptr[1])(*this);
}
void fun2(){
fun1();
}
private:
static void func1_def(Base& pseudo_obj_arg){
Base* this=&pseudo_obj_arg;
std::cout<<"Hello Base"<<std::endl;
}
static void* vtable[2];
};
void* Base::vtable[2]={
reinterpret_cast<void*>(&type_id_of_Base),
reinterpret_cast<void*>(&Base::func1_def)};
class Derived: public Base
{
int a;
//Executed after Base intialization,
//before Derived member initialization.
//Reexecuted prior to Derived destructor call
void set_dynamic_type(){
Base::vt_ptr = Derived::vtable;
}
private:
static void func1_def(Base& pseudo_obj_arg){
Derived* this=static_cast<Derived*>(&pseudo_obj_arg);
std::cout<<"Hello Derived"<<std::endl;
}
static void* vtable[2];
};
void* Derived::vtable[2]={
reinterpret_cast<void*>(&type_id_of_Derived),
reinterpret_cast<void*>(&Derived::func1_def)};
還有一個合格的調用,例如: obj.Base::func1()
直接調用Base::func1_def(obj)
,否則它將引發Base::func1
中描述的去虛擬化過程。
虛擬表是在構造類對象時創建的。 構造Derived
對象時,它將首先調用Base
構造函數(它將創建vtable並將其自身寫入Base::fun1
。然后, Derived
構造函數將運行並使用其自己的實現覆蓋fun1
的vtable條目( Derived::fun1
)。
如果這樣,那么在以后的任何時刻(甚至從任何Base
函數中)調用此類對象實例的fun1
,它都將調查vtable並調用在其中找到的任何函數。 如上所述,構造后,它位於Derived
對象的vtable中的Derived::fun1
,因此將被調用。 無論您當前是否處於Base
函數中,vtable條目都不會更改。
請注意, 在構建過程中 ,尚未完全建立vtable:如果要從Base
構造函數中調用fun1
,則不會調用Derived::fun1
而是Base::fun1
因為Derived
尚未替換vtable條目。
還要注意,完全指定函數(例如,在Derived
實例上調用Base::fun1()
)不會執行vtable查找,而是完全使用指定的函數。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.