列印虛函式表
#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...