在c++中虚函数的实现是通过一张表虚函数表(V-table)来实现的,c++的编译器在编译的时候会将虚函数表放在实例的最前面。这个是可以通过代码来验证的。
在c++中虚函数的实现是通过一张表虚函数表(V-table)来实现的,c++的编译器在编译的时候会将虚函数表放在实例的最前面。这个是可以通过代码来验证的。
假设我们有这样的一个类
class base
{
virtual void print( void){
cout << "这是base类" << endl;
}
virtual void print2( void){
cout << "base" << endl;
}
};
然后我们可以通过指针来访问虚函数表中的函数
typedef void(* fun)(void );
base b1 ;
cout << "虚函数表地址" << (int *)(&b1 ) << endl;
cout << "虚函数表的第一个函数地址" << (int*)*(( int*)(&b1 ))<< endl ;
fun pfun = (fun)*(( int*)*((int *)(&b1)));
pfun();
getchar();
有这样的一个子类
class child :public base
{
virtual void print( void){
cout << "这是子类" << endl;
}
virtual void print3( void){
cout << "printf3" << endl;
}
};
主函数中改成这样
typedef void(* fun)(void );
base b1 ;
child c1 ;
cout << "虚函数表地址" << (int *)(&b1 ) << endl;
cout << "虚函数表的第一个函数地址" << (int*)*(( int*)(&b1 ))<< endl ;
fun pfun = (fun)*(( int*)*((int *)(&c1)));
pfun();
fun pfun2 = (fun)*(( int*)*((int *)(&c1))+ 1);
pfun2();
fun pfun3 = (fun)*(( int*)*((int *)(&c1))+ 2);
pfun3();
输出结果
从结果中可以看出,在子类中重载父类虚函数的话,在子类的虚函数表中子类的这个函数地址会覆盖父类函数地址,没有重载的话,父类函数地址排在子类前面