c++虚函数实现与this指针

我们知道当我们sizeof 一个类的时候,类的成员函数是不计算在对象的大小的里的,这是为什么呢?因为类的成员函数不是属于某一个对象的,而是类的所有对象所共享的,就像static变量那样。如果虚函数和普通成员函数一样,那么我们就不能通过指向子类的基类指针来引用子类的方法了,因为我们将不知道调用哪个方法,多态就无从谈起。那么多态是怎么实现的呢?

  • 虚函数、虚指针与虚表

我们可以做一个小实验

class A{
public:
        int a;
        virtual void myfun(){}
};

class B:public A{
public:
        int b;
 };
B obj_b;
obj_b.a=1;
obj_b.b=2; A
*p=&B; cout<<p<<endl; cout<<&(p->a)<<endl;
cout<<p->a<<'\t'<<*(&(p->a)+1)<<endl;

p的值和&(p->a)的值是相差4个字节的,最后一行输出的值为1 ,2。我们可以推断出obj_b在内存中的分布是首先一个占有4字节的某类型,然后是int a,最后是int b。

初始的4字节其实就是虚指针。

而类A的对象在内存的分布其实是虚指针然后是int a。

如果类B继承A,在B构造的时候,会继承虚指针和int a,但是虚指针指向的虚表就不同了。若在B中实现了虚函数则虚表中的对应函数的入口地址也会改变。从而达到多态的目的。

注意指针p并访问不到b,因为p是A类型的指针,可见指针的访问范围由的类型决定了。所以我们通过&(p->a)+1来访问b。

 

 

那么多重继承时是什么情况呢?

多重继承的时候,对于每个有虚函数的基类,子类都会继承相应的虚指针并改写虚表。

  • this指针

我觉得一篇blog写的挺好就引用过来了。博客地址为:http://www.cnblogs.com/CCQLegend/p/3270738.html

 

 

this指针跟不少人想象的不一样,它的类型由被调用函数决定。它的类型遵循着这两点规则:(途中打勾为首地址。)

1.对于非虚函数,this指针的基准地址为函数定义所在层级对象的首地址,范围为该层级对象始末。

如:IA::FF();

this指针类型是以D0H为首地址,范围是从首地址开始到DFH为止。(其实里面有内存空洞,我们不去纠结这个)

Derived::FF();

this指针类型是C0H为首地址,范围是从首地址到E8H为止。

2.对于虚函数,this指针的基准地址为函数首先声明者的首地址,范围为实现者的始末。

如:IA::F();

其this指针类型是以D0H为首地址,范围是从首地址开始到DFH为止。

Derived::F();

其this指针类型是以D0H为首地址,范围是从C0H到E8H为止。

那么当有IA* a=new Derived();后,

a->F();便是这么访问b成员的了。假设首地址D0H保存在寄存器rax里,

rax-8

 

转载于:https://www.cnblogs.com/coderht/p/7436860.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值