單繼承類的虛函式表

2021-10-06 21:50:00 字數 4170 閱讀 9409

列印虛函式表

#include

#include

using

namespace std;

class

classa

int m_data1;

int m_data2;

void

func1()

void

func2()

virtual

void

vfunc1()

virtual

void

vfunc2()

};class

classb

:public classa

int m_data3;

void

func2()

virtual

void

vfunc1()

};class

classc

:public classb

int m_data1;

int m_data4;

void

func2()

virtual

void

vfunc1()

};intmain()

執行結果:

classa.vptr=

0xfff656e8 classa.vtbl[0]

=0x5664ae88

classa vtbl[0]

=0x566491d0

// 0x5664ae88

classa vtbl[1]

=0x56649216

// 0x5664ae8c

classa vtbl[2]

=0xf7f6e0ec

// 0x5664ae90 注意:這裡不是結束符

classa vtbl[3]

=0x566496a8

// 0x5664ae94

classa vtbl[4]

=0x5664ae9c

// 0x5664ae98

classa vtbl[5]

=0xf7f6e0ec

// 0x5664ae9c

classb.vptr=

0xfff656f4 classb.vtbl[0]

=0x5664ae78

classb vtbl[0]

=0x566492de

// 0x5664ae78

classb vtbl[1]

=0x56649216

// 0x5664ae7c

classb vtbl[2]

=0// 0x5664ae80

classb vtbl[3]

=0x5664aea8

// 0x5664ae84

classb vtbl[4]

=0x566491d0

// 0x5664ae88

classb vtbl[5]

=0x56649216

// 0x5664ae8c

classc.vptr=

0xfff65704 classc.vtbl[0]

=0x5664ae68

classc vtbl[0]

=0x566493b0

// 0x5664ae68

classc vtbl[1]

=0x56649216

// 0x5664ae6c

classc vtbl[2]

=0// 0x5664ae70

classc vtbl[3]

=0x5664ae9c

// 0x5664ae74

classc vtbl[4]

=0x566492de

// 0x5664ae78

classc vtbl[5]

=0x56649216

// 0x5664ae7c

遇到問題:classb.vtbl[2]=0和classc.vtbl[2]=0,說明虛函式表的結束符應該是0,但為什麼classa的虛函式表中又沒有出現呢?

下面通過函式指標指向虛函式表的值,再呼叫成員函式,看虛函式表中放了什麼

#include

#include

using

namespace std;

class

classa

int m_data1;

int m_data2;

void

func1()

void

func2()

virtual

void

vfunc1()

virtual

void

vfunc2()

};class

classb

:public classa

int m_data3;

void

func2()

virtual

void

vfunc1()

};class

classc

:public classb

int m_data1;

int m_data4;

void

func2()

virtual

void

vfunc1()

};intmain()

pfun()

;}cout << endl;

v =(long*)

&b; vtbl0 =

(long*)

(*v)

; cout <<

"classb.vptr="

<< v <<

" classb.vtbl[0]="

<< vtbl0 << endl;

for(

int i =

0; i<6;

++i)

pfun()

;}cout << endl;

v =(long*)

&c; vtbl0 =

(long*)

(*v)

; cout <<

"classc.vptr="

<< v <<

" classc.vtbl[0]="

<< vtbl0 << endl;

for(

int i =

0; i <6;

++i)

pfun()

;}cout << endl;

return0;

}

執行結果:

classa.vptr=

0xff804738 classa.vtbl[0]

=0x565c0e88

classa vtbl[0]

=0x565bf2c0

0x565c0e88 classa::vfunc1

classa vtbl[1]

=0x565bf306

0x565c0e8c classa::vfunc2

classb.vptr=

0xff804744 classb.vtbl[0]

=0x565c0e78

classb vtbl[0]

=0x565bf3ce

0x565c0e78 classb::vfunc1 //子類override後,虛函式表也發生了變化

classb vtbl[1]

=0x565bf306

0x565c0e7c classa::vfunc2

classb vtbl[2]

=00x565c0e80

classc.vptr=

0xff804754 classc.vtbl[0]

=0x565c0e68

classc vtbl[0]

=0x565bf4a0

0x565c0e68 classc::vfunc1 //子類override後,虛函式表也發生了變化

classc vtbl[1]

=0x565bf306

0x565c0e6c classa::vfunc2

classc vtbl[2]

=00x565c0e70

單繼承和多繼承的虛函式表

前面兩篇關於多型的部落格已經詳細介紹了多型的基礎知識點和多型的底層實現原理,下面將主要介紹一下單繼承和多繼承的虛函式表 首先來看一段 class base virtual void func2 private int b 1 class derive public base virtual void...

c 類大小(涵蓋繼承 虛繼承 虛函式表)

涉及到c 中求類大小時需要特別注意一下幾點 為類的非靜態成員資料的型別大小之和 有編譯器額外加入的成員變數的大小,用來支援語言的某些特性 如 指向虛函式的指標 虛繼承 多重繼承 為了優化訪問效率,進行的邊緣調整 與類中的建構函式,析構函式以及其他的成員函式無關 5.私有繼承,會去繼承之前的私有成員變...

虛繼承與虛函式表

一 虛繼承 1 include iostream using namespace std class bvoid fb class d1 virtual public bvoid fd1 class d2 virtual public bvirtual void vd2 void fd2 class...