深度探索C++对象模型笔记 —— 第四章

深度探索C++对象模型 专栏收录该内容
7 篇文章 0 订阅
  1. 静态成员函数不能直接存取其class中的nonstatic members;不能够被声明Wieconst,volatile或virtual;它不需要经由class object才被调用——虽然大部分时候它是这样被调用的
  2. 在这里插入图片描述
    ptr->z();
    一般而言,每次调用z()时,并不知道ptr所指对象的真正类型,然而我们知道经由ptr可以存取到该对象的virtual table;虽然不知道哪一个z()函数实例会被调用,但是知道每一个z()函数地址都被放在slot4中,这些信息使得编译器可以将调用转化为(*ptr->vptr[4])(ptr);这一转化中,vptr表示编译器所安插的指针,指向virtual table;4表示z()被指派的slot编号(关系到Point体系的virtual table)。唯一一个在执行期才能知道的东西是:slot4所指的到底是哪一个z()函数实例
  3. 在这里插入图片描述
    有三种情况,第二或后继的base class会影响对virtual functions的支持。
    1) 通过一个“指向第二个base class”的指针,调用derived class virtual functions,例如
    Base2* ptr=new Derived;
    //调用 Derived::~Derived
    //ptr必须向后调整sizeof(Base1) 个bytes
    delete ptr;
    ptr指向Derived对象中的Base2 subobject,为了能够正确执行,ptr必须调整指向Derived对象的起始处。
    2) 通过一个指向Derived class的指针,调用第二个base class中一个继承而来的virtual function,在此情况下,derived class指针必须再次调整,以指向第二个base subobject,例如
    Derived* pder=new Derived;
    //调用 Based2::mumble()
    //pder必须被向前调整sizeof(Base1)个bytes
    pder->mumber();
    3)第三种情况发生于一个语言扩充性质之下:允许一个virtual function的返回值类型有所变化,可能是base type,也可能是publicly derived type。这一点可以经由Derived::clone()函数来说明(virtual Derived* clone() const)。clone函数的Derived版本传回一个Derived class指针,默默地改写了它的两个base class函数实例。当我们通过指向第二个base class的指针来调用clone()时,this指针的offset问题于是诞生了:
    Base2* pb1=new Derived;
    //调用 Derived* Derived::clone()
    //返回值必须被调整,以指向Base2 subobject
    Base2 *pb2=pb->clone();
    当进行pb1->clone()时,pb1会被调整指向Derived对象的起始地址,于是clone()的Derived版会被调用,它会传回一个指针,指向一个新的Derived 对象,该对象的地址在被指定给pb2之前,必须先经过调整,以指向Base2 subobject
  4. 使用一个“member function”指针,如果不用于virtual function,多重继承,virtual base class等情况的话,并不会比使用一个“nonmember function指针”的成本更高
  5. 面对一个virtual function,其地址在编译时期是未知的,所能知道的仅是virtual function在其相关之virtual table中的索引值,所以对一个virtual member function取地址,得到的是一个索引值
  • 0
    点赞
  • 0
    评论
  • 0
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值