溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

虛函數(shù)——虛表總結

發(fā)布時間:2020-07-31 01:00:29 來源:網(wǎng)絡 閱讀:610 作者:I慕藍 欄目:編程語言

非虛擬繼承

帶虛函數(shù)的類

class Base

{

public:

virtual void FunTest1()

{

cout<<"Base::FunTest1()"<<endl;

}

 

virtual void FunTest2()

{

cout<<"Base::FunTest2()"<<endl;

}

 

int _data1;

};

 

int main()

{

Base b;

b._data1 = 0x01;

return 0;

}

 

Base類沒有顯式定義自己的構造函數(shù),此時編譯器會和成默認的構造函數(shù),

虛函數(shù)——虛表總結

合成的構造函數(shù)中主要完成在對象頭4個字節(jié)中填寫虛表地址:

虛函數(shù)——虛表總結

Base類對象最后的模型如下:

虛函數(shù)——虛表總結

注意:同一個類的對象共用同一個虛表

虛函數(shù)——虛表總結

從上述的結果中可以得到印證。

【單繼承(派生類中沒有虛函數(shù)覆蓋)

class Base

{

public:

virtual void FunTest1()

{cout<<"Base::FunTest1()"<<endl;}

 

virtual void FunTest2()

{cout<<"Base::FunTest2()"<<endl;}

           int _data1;

};

 

class Derive:public Base

{

public:

virtual void FunTest3()

{cout<<"Derive::FunTest3()"<<endl;}

 

virtual void FunTest4()

{cout<<"Derive::FunTest4()"<<endl;}

 int _data2;

};

 

// 打印虛表

typedef void (*VtbFun)();

void PrintVtable()

{

cout<<"Derive類的虛函數(shù)表:"<<endl;

Derive d1;

d1._data1 = 0x01;

d1._data2 = 0x02;

 

int* pVTable = (int*)*(int*)&d1;

VtbFun FunTest = (VtbFun)*pVTable;

while(NULL != FunTest)

{

FunTest();

cout<<(int*)FunTest<<endl;

pVTable += 1;

FunTest = (VtbFun)*pVTable;

}

 

cout<<"虛表結束:"<<endl;

}

 

int main()

{

Base b1;

Derive d1;

return 0;

}

 

按照如上分析的順序,探索下單繼承下派生類對象模型以及虛表

首先看看編譯器為派生類合成的缺省構造函數(shù):

虛函數(shù)——虛表總結

派生類構造函數(shù)中進行了如下事情:

虛函數(shù)——虛表總結

Derive d1;

d1._data1 = 0x01;

d1._data2 = 0x02;

派生類最后的對象模型為:

虛函數(shù)——虛表總結

【單繼承(派生類中有虛函數(shù)覆蓋)

class Base

{

public:

virtual void FunTest1()

{

cout<<"Base::FunTest1()"<<endl;

}

 

virtual void FunTest2()

{

cout<<"Base::FunTest2()"<<endl;

}

 

int _data1;

};

 

class Derive:public Base

{

public:

virtual void FunTest1()

{

cout<<"Derive::FunTest1()"<<endl;

}

 

virtual void FunTest3()

{

cout<<"Derive::FunTest3()"<<endl;

}

 

virtual void FunTest4()

{

cout<<"Derive::FunTest4()"<<endl;

}

int _data2;

};

 

int main()

{

PrintVtable();

return 0;

}

 

派生類對象模型及虛表建議規(guī)則:

虛函數(shù)——虛表總結

【多繼承(派生類不覆蓋基類虛函數(shù))

class Base

{

public:

virtual void FunTest1()

{

cout<<"Base::FunTest1()"<<endl;

}

 

virtual void FunTest2()

{

cout<<"Base::FunTest2()"<<endl;

}

 

int _data1;

};

 

class Base1

{

public:

virtual void FunTest3()

{

cout<<"Base1::FunTest3()"<<endl;

}

 

virtual void FunTest4()

{

cout<<"Base1::FunTest4()"<<endl;

}

 

int _data2;

};

 

class Derive:public Base, public Base1

{

public:

virtual void FunTest5()

{

cout<<"Derive::FunTest5()"<<endl;

}

 

int _data3;

};

 

int main()

{

cout<<"sizeof(Derive) = "<<sizeof(Derive)<<endl;

Derive d;

d._data1 = 0x01;

d._data2 = 0x02;

d._data3 = 0x03;

PrintVtable();

return 0;

}

 

同樣:看看編譯器合成的派生類的對象做了什么工作

虛函數(shù)——虛表總結

觀察下派生類的對象模型和虛表的建立過程

虛函數(shù)——虛表總結

從上面的結果可以看出,Derive類自己特有的虛函數(shù)直接添加在Base類對應虛函數(shù)表最后的位置,大家可將BaseBase1的順序交換驗證下。

 

【多繼承(派生類覆蓋基類虛函數(shù))

class Base

{

public:

virtual void FunTest1()

{

cout<<"Base::FunTest1()"<<endl;

}

 

virtual void FunTest2()

{

cout<<"Base::FunTest2()"<<endl;

}

 

int _data1;

};

 

class Base1

{

public:

virtual void FunTest3()

{

cout<<"Base1::FunTest3()"<<endl;

}

 

virtual void FunTest4()

{

cout<<"Base1::FunTest4()"<<endl;

}

 

int _data2;

};

 

// 這次將繼承列表中BaseBase1的位置互換

class Derive:public Base1, public Base

{

public:

virtual void FunTest1()

{

cout<<"Derive::FunTest1()"<<endl;

}

virtual void FunTest3()

{

cout<<"Derive::FunTest3()"<<endl;

}

virtual void FunTest5()

{

cout<<"Derive::FunTest5()"<<endl;

}

 

int _data3;

};

 

int main()

{

           PrintVtable();

return 0;

}

 

此時派生類的對象模型和虛表的結構:

虛函數(shù)——虛表總結

虛擬繼承

// 沒有虛函數(shù)覆蓋,但派生類有自己的虛函數(shù)

class Base

{

public:

virtual void FunTest1()

{

cout<<"Base::FunTest1()"<<endl;

}

 

virtual void FunTest2()

{

cout<<"Base::FunTest2()"<<endl;

}

 

int _data1;

};

 

class Derive:virtual public Base

{

public:

virtual void FunTest3()

{

cout<<"Derive::FunTest3()"<<endl;

}

virtual void FunTest4()

{

cout<<"Derive::FunTest4()"<<endl;

}

 

int _data2;

};

 

虛擬繼承編譯器為派生類合成的默認構造函數(shù)分析

虛函數(shù)——虛表總結

編譯器為派生類合成的默認構造函數(shù)任務分析:

虛函數(shù)——虛表總結虛函數(shù)——虛表總結

虛擬繼承派生類對象模型分析

虛函數(shù)——虛表總結

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權內(nèi)容。

AI