虚函数表、vptr指针、父类指针和子类指针

虚函数表和vptr指针

通过virtual关键字修饰函数,可以实现多态,本质是编译器会在类中生成一个虚函数表,在给对象开辟空间时会默认增加一个指针vptr,这个指针指向虚函数表;

一个vptr指针占4个字节长度,通过virtual修饰函数时就会创建且只创建一个vptr指针,长度不变,所以增加virtual函数数量,vptr不变;

父类和子类各有自身的虚函数表;

只有调用虚函数时才会查找虚函数表;

实现多态的本质是对象指针指向vptr(默认),当把子类对象地址赋给父类对象时,父类指针就指向子类vptr,调用虚函数(多态)时就会在相应虚函数表中查找;

如果不是虚函数,即使把子类对象赋给父类指针,首先仍然在子类虚函数表中查找,然后在父类普通函数中查找调用父类相应的函数,这就是非多态的本质。

虚函数效率要低,所以没有必要时不建议把所有成员函数都定义成虚函数;

验证vptr指针的方法(vptr指针不可访问),就是先求一个普通类占的字节数大小sizeof(Parent),然后将类中某一个函数(方法)前加virtual关键字变为虚函数,再求该类占的字节数大小sizeof(Parent),会发现增加4个字节,这就验证了vptr的存在。

 

 

父类指针、子类指针,如指针Parent *p,p++代表移动一个步长sizeof(Parent)的大小,所以不能通过父类指针指向子类对象空间然后采用p++的方式循环遍历,因为子类指针和父类指针步长不一定相同!

一般在定义指针时都要赋值为NULL(代表没有使用值,如果初始不置为空,那么就表示其有合法值,实际并不一定),防止其变为野指针(指向任意一个区间),如果这样定义Parent *p,再if(p!=NULL){ free(p); },这样就会出现问题。实际上,一般都要求,定义任何变量都要有初始化值,如int a = 0,int *p = NULL。

 

转载于:https://www.cnblogs.com/zzx1905/p/virtual_vptr_step.html

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值