【C++学习】| (03)虚函数 虚指针 虚表

虚函数

对于类的成员函数,如果在前面加上virtual,那么这个成员函数就是虚函数,这个类就是带有虚函数的类。

虚指针,虚表

带没有虚函数的类,与不带虚函数的类之间有什么区别呢?带有虚函数的类比不带虚函数的类会多一个指针,这个指针就是虚指针,而虚指针指向一个表,这个表就叫做虚表。虚表里面存的内容就是虚函数的地址。

例子:
#include <iostream>
using namespace std;
 
class Base{/*该类中函数均为虚函数*/
public:
    virtual void f(){cout<<"Base::f()"<<endl;}
    virtual void g(){cout<<"Base::g()"<<endl;}
    virtual void h(){cout<<"Base::h()"<<endl;}
    Base() : a(0),b(1) {   }
private:
    int a;
    int b;
};
class Base_Two{/*该类中函数均为非虚函数*/
public:
    void f(){cout<<"Base::f()"<<endl;}
    void g(){cout<<"Base::g()"<<endl;}
    void h(){cout<<"Base::h()"<<endl;}
    Base_Two() : a(0), b(1) {   }
private:
    int a;
    int b;
};
int main()
{
    Base b;
    cout<<"Virtual function:"<<sizeof(Base)<<endl;
    cout<<"Virtual function:"<<sizeof(b)<<endl;
 
    Base_Two b2;
    cout<<"Ordinary function:"<<sizeof(Base_Two)<<endl;
    cout<<"Ordinary function:"<<sizeof(b2)<<endl;
 
    cout << "指针长度 = " << sizeof(int *) << endl;
    
 
    return 0;
}

结果:

Virtual function:16
Virtual function:16
Ordinary function:8
Ordinary function:8
指针长度 = 8
从结果可以看出,带虚函数的类比不带虚函数的类多出来了一个指针的长度,我的指针长度是8,根据系统环境不同也有可能是4,从调试结果也可以明显看出来:

进一步用代码验证:
#include <iostream>
using namespace std;
 
class Base{/*该类中函数均为虚函数*/
public:
    virtual void f(){cout<<"Base::f()"<<endl;}
    virtual void g(){cout<<"Base::g()"<<endl;}
    virtual void h(){cout<<"Base::h()"<<endl;}
    Base() : a(0),b(1) {   }
private:
    int a;
    int b;
};
 
int main()
{
    Base b;
    cout<<"Object start address:"<<&b<<endl;//对象起始地址
    cout<<"Virtual function table start address:";//V-Table起始地址
    cout<<(int **)(*(int *)(&b))<<endl;
 
    cout<<"Function address in virtual function table:"<<endl;
    cout<<((int **)(*(int *)&b))[0]<<endl;
    cout<<((int **)(*(int *)&b))[1]<<endl;
    cout<<((int **)(*(int *)&b))[2]<<endl;
    cout<<((int **)(*(int *)&b))[3]<<endl;
     /****************************
      表达式分析:
      (int *)&b:取对象b地址的前四个字节,即vptr的地址
      *(int *)&b:取vptr的存储的地址值
      (int **)(*(int *)&b):将该地址值转换成二级指针,即存放虚函数地址(一级指针)的虚表数组地址
      ((int **)(*(int *)&b))[i]:根据该虚表地址进行下标运算取具体的(第i个)虚函数地址
    *******************************/
  
 
    return 0;
}

结果:

Object start address:0x70fe40
Virtual function table start address:0x4863b0
Function address in virtual function table:
0x41e420
0x41e460
0x41e4a0
0

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值