zoukankan      html  css  js  c++  java
  • C++类内存分布

    来源:https://www.cnblogs.com/jerry19880126/p/3616999.html

    书上类继承相关章节到这里就结束了,这里不妨说下C++内存分布结构,我们来看看编译器是怎么处理类成员内存分布的,特别是在继承、虚函数存在的情况下。 

    32bit程序:

    工欲善其事,必先利其器,我们先用好Visual Studio工具,像下面这样一步一步来:

    先选择左侧的C/C++->命令行,然后在其他选项这里写上/d1 reportAllClassLayout,它可以看到所有相关类的内存布局,如果写上/d1 reportSingleClassLayoutXXX(XXX为类名),则只会打出指定类XXX的内存布局。近期的VS版本都支持这样配置。

    下面可以定义一个类,像下面这样:

    复制代码
    1 class Base
    2 {
    3     int a;
    4     int b;
    5 public:
    6     void CommonFunction();
    7 };
    复制代码

    然后编译一下,可以看到输出框里面有这样的排布:

    这里不想花精力在内存对齐因素上,所以成员变量都设为int型。

    从这里可以看到普通类的排布方式,成员变量依据声明的顺序进行排列(类内偏移为0开始),成员函数不占内存空间。

    再看下继承,往后面添加如下代码:

    复制代码
    1 class DerivedClass: public Base
    2 {
    3     int c;
    4 public:
    5     void DerivedCommonFunction();
    6 };
    复制代码

    编译,然后看到如下的内存分布(父类的内存分布不变,这里只讨论子类成员变量的内存分布):

    可以看到子类继承了父类的成员变量,在内存排布上,先是排布了父类的成员变量,接着排布子类的成员变量,同样,成员函数不占字节。

    下面给基类加上虚函数,暂时注释掉DerivedClass,看一下这时的内存排布:

    复制代码
    1 class Base
    2 {
    3     int a;
    4     int b;
    5 public:
    6     void CommonFunction();
    7     void virtual VirtualFunction();
    8 };
    复制代码

    这个内存结构图分成了两个部分,上面是内存分布,下面是虚表,我们逐个看。VS所带编译器是把虚表指针放在了内存的开始处(0地址偏移),然后再是成员变量;下面生成了虚表,紧跟在&Base1_meta后面的0表示,这张虚表对应的虚指针在内存中的分布,下面列出了虚函数,左侧的0是这个虚函数的序号,这里只有一个虚函数,所以只有一项,如果有多个虚函数,会有序号为1,为2的虚函数列出来。

    编译器是在构造函数创建这个虚表指针以及虚表的。

    那么编译器是如何利用虚表指针与虚表来实现多态的呢?是这样的,当创建一个含有虚函数的父类的对象时,编译器在对象构造时将虚表指针指向父类的虚函数;同样,当创建子类的对象时,编译器在构造函数里将虚表指针(子类只有一个虚表指针,它来自父类)指向子类的虚表(这个虚表里面的虚函数入口地址是子类的)。

    所以,如果是调用Base *p = new Derived();生成的是子类的对象,在构造时,子类对象的虚指针指向的是子类的虚表,接着由Derived*到Base*的转换并没有改变虚表指针,所以这时候p->VirtualFunction,实际上是p->vfptr->VirtualFunction,它在构造的时候就已经指向了子类的VirtualFunction,所以调用的是子类的虚函数,这就是多态了。

    下面加上子类,并在子类中添加虚函数,像下面这样:

    复制代码
    1 class DerivedClass: public Base
    2 {
    3     int c;
    4 public:
    5     void DerivedCommonFunction();
    6     void virtual VirtualFunction();
    7 };
    复制代码

    可以看到子类内存的排布如下:

    上半部是内存分布,可以看到,虚表指针被继承了,且仍位于内存排布的起始处,下面是父类的成员变量a和b,最后是子类的成员变量c,注意虚表指针只有一个,子类并没有再生成虚表指针了;下半部的虚表情况与父类是一样的。

    我们把子类换个代码,像这样:

    复制代码
    1 class DerivedClass1 : public Base
    2 {
    3     int c;
    4 public:
    5     void DerivedCommonFunction();
    6     void virtual VirtualFunction2();
    7 };
    复制代码

    注意到这时我们并没有覆写父类的虚方法,而是重声明了一个新的子类虚方法,内存分布如下:

    还是只有一个虚表指针,但是下方虚表的内容变化了,虚表的0号是父类的VirtualFunction,而1号放的是子类的VirtualFunction2。也就是说,如果定义了DerivedClass的对象,那么在构造时,虚表指针就会指向这个虚表,以后如果调用的是VirtualFunction,那么会从父类中寻找对应的虚函数,如果调用的是VirtualFunction2,那么会从子类中寻找对应的虚函数。

    我们再改造一下子类,像这样:

    复制代码
    1 class DerivedClass1 : public Base
    2 {
    3     int c;
    4 public:
    5     void DerivedCommonFunction();
    6     void virtual VirtualFunction();
    7     void virtual VirtualFunction2();
    8 };
    复制代码

    我们既覆写父类的虚函数,也有新添的虚函数,那么可以料想的到,是下面的这种内存分布:

    下面来讨论多重继承,代码如下:

    复制代码
     1 class Base
     2 {
     3     int a;
     4     int b;
     5 public:
     6     void CommonFunction();
     7     void virtual VirtualFunction();
     8 };
     9 
    10 
    11 class DerivedClass1: public Base
    12 {
    13     int c;
    14 public:
    15     void DerivedCommonFunction();
    16     void virtual VirtualFunction();
    17 };
    18 
    19 class DerivedClass2 : public Base
    20 {
    21     int d;
    22 public:
    23     void DerivedCommonFunction();
    24     void virtual VirtualFunction();
    25 };
    26 
    27 class DerivedDerivedClass : public DerivedClass1, public DerivedClass2
    28 {
    29     int e;
    30 public:
    31     void DerivedDerivedCommonFunction();
    32     void virtual VirtualFunction();
    33 };
    复制代码

    内存分布从父类到子类,依次如下:

    Base中有一个虚表指针,地址偏移为0

    DerivedClass1继承了Base,内存排布是先父类后子类。

    DerivedClass2的情况是类似于DerivedClass1的。

    下面我们重点看看这个类DerivedDerivedClass,由外向内看,它并列地排布着继承而来的两个父类DerivedClass1与DerivedClass2,还有自身的成员变量e。DerivedClass1包含了它的成员变量c,以及Base,Base有一个0地址偏移的虚表指针,然后是成员变量a和b;DerivedClass2的内存排布类似于DerivedClass1,注意到DerivedClass2里面竟然也有一份Base。

    这里有两份虚表了,分别针对DerivedClass1与DerivedClass2,在&DerivedDericedClass_meta下方的数字是首地址偏移量,靠下面的虚表的那个-16表示指向这个虚表的虚指针的内存偏移,这正是DerivedClass2中的{vfptr}在DerivedDerivedClass的内存偏移。

    如果采用虚继承,像下面这样:

    复制代码
     1 class DerivedClass1: virtual public Base
     2 {
     3     int c;
     4 public:
     5     void DerivedCommonFunction();
     6     void virtual VirtualFunction();
     7 };
     8 
     9 class DerivedClass2 : virtual public Base
    10 {
    11     int d;
    12 public:
    13     void DerivedCommonFunction();
    14     void virtual VirtualFunction();
    15 };
    16 
    17 class DerivedDerivedClass :  public DerivedClass1, public DerivedClass2
    18 {
    19     int e;
    20 public:
    21     void DerivedDerivedCommonFunction();
    22     void virtual VirtualFunction();
    23 };
    复制代码

    Base类没有变化,但往下看:

    DerivedClass1就已经有变化了,原来是先排虚表指针与Base成员变量,vfptr位于0地址偏移处;但现在有两个虚表指针了,一个是vbptr,另一个是vfptr。vbptr是这个DerivedClass1对应的虚表指针,它指向DerivedClass1的虚表vbtable,另一个vfptr是虚基类表对应的虚指针,它指向vftable。

    下面列出了两张虚表,第一张表是vbptr指向的表,8表示{vbptr}与{vfptr}的偏移;第二张表是vfptr指向的表,-8指明了这张表所对应的虚指针位于内存的偏移量。

    DerivedClass2的内存分布类似于DerivedClass1,同样会有两个虚指针,分别指向两张虚表(第二张是虚基类表)。

    下面来仔细看一下DerivedDerivedClass的内存分布,这里面有三个虚指针了,但base却只有一份。第一张虚表是内含DerivedClass1的,20表示它的虚指针{vfptr}离虚基表指针{vbptr}的距离,第二张虚表是内含DerivedClass2的,12表示它的虚指针{vfptr}离虚基表指针{vbptr}的距离,最后一张表是虚基表,-20指明了它对应的虚指针{vfptr}在内存中的偏移。

    虚继承的作用是减少了对基类的重复,代价是增加了虚表指针的负担(更多的虚表指针)。

    下面总结一下(当基类有虚函数时):

    1. 每个'有virtual函数的类'都有'虚函数表指针'和'虚函数表';

    2. 如果不是虚继承:那么子类将父类的'虚函数表指针'继承下来,并指向自身的'虚函数表'(发生在对象构造时)。有多少个虚函数,'虚函数表'里面的项就会有多少。多重继承时,基类'虚函数表'与'虚函数表指针'存在多个

    3. 如果是虚继承:那么子类会有两种虚指针,'虚函数表指针'指向自己的'虚函数表';'虚基类表指针'指向'虚基类表'。多重继承时,'虚函数表'与'虚函数表指针'有且只有一份,'虚基类表指针'与'虚基类表'存在多个。

    64bit程序:

    一般继承

     1 class Base
     2 {
     3     int a;
     4     int b;
     5 public:
     6     void CommonFunction();
     7     void virtual VirtualFunction();
     8 };
     9 
    10 class DerivedClass1 : public Base
    11 {
    12     int c;
    13 public:
    14     void DerivedCommonFunction();
    15     void virtual VirtualFunction();
    16 };
    17 
    18 class DerivedClass2 : public Base
    19 {
    20     int d;
    21 public:
    22     void DerivedCommonFunction();
    23     void virtual VirtualFunction();
    24 };
    25 
    26 class DerivedDerivedClass : public DerivedClass1, public DerivedClass2
    27 {
    28     int e;
    29 public:
    30     void DerivedDerivedCommonFunction();
    31     void virtual VirtualFunction();
    32 };
    class Base    size(16):
        +---
     0    | {vfptr}
     8    | a
    12    | b
        +---
    
    Base::$vftable@:
        | &Base_meta
        |  0
     0    | &Base::VirtualFunction
    
    Base::VirtualFunction this adjustor: 0       只要有虚函数,就有这条
    
    class DerivedClass1    size(24):
        +---
     0    | +--- (base class Base)
     0    | | {vfptr}
     8    | | a
    12    | | b
        | +---
    16    | c
          | <alignment member> (size=4)
        +---
    
    DerivedClass1::$vftable@:
        | &DerivedClass1_meta
        |  0
     0    | &DerivedClass1::VirtualFunction
    
    DerivedClass1::VirtualFunction this adjustor: 0
    
    class DerivedClass2    size(24):
        +---
     0    | +--- (base class Base)
     0    | | {vfptr}
     8    | | a
    12    | | b
        | +---
    16    | d
          | <alignment member> (size=4)
        +---
    
    DerivedClass2::$vftable@:
        | &DerivedClass2_meta
        |  0
     0    | &DerivedClass2::VirtualFunction
    
    DerivedClass2::VirtualFunction this adjustor: 0
    
    class DerivedDerivedClass    size(56):
        +---
     0    | +--- (base class DerivedClass1)
     0    | | +--- (base class Base)
     0    | | | {vfptr}
     8    | | | a
    12    | | | b
        | | +---
    16    | | c
          | | <alignment member> (size=4)
        | +---
    24    | +--- (base class DerivedClass2)
    24    | | +--- (base class Base)
    24    | | | {vfptr}
    32    | | | a
    36    | | | b
        | | +---
    40    | | d
          | | <alignment member> (size=4)
        | +---
    48    | e
          | <alignment member> (size=4)
        +---
    
    DerivedDerivedClass::$vftable@DerivedClass1@:           表示DerivedDerivedClass的一个$vftable相对于DerivedClass1来说在0处
        | &DerivedDerivedClass_meta
        |  0
     0    | &DerivedDerivedClass::VirtualFunction
    
    DerivedDerivedClass::$vftable@DerivedClass2@:           表示DerivedDerivedClass的一个$vftable相对于DerivedClass2来说在-24处
        | -24
     0    | &thunk: this-=24; goto DerivedDerivedClass::VirtualFunction
    
    DerivedDerivedClass::VirtualFunction this adjustor: 0

    虚继承

     1 class Base
     2 {
     3     int a;
     4     int b;
     5 public:
     6     void CommonFunction();
     7     void virtual VirtualFunction();
     8 };
     9 
    10 class DerivedClass1 : virtual public Base
    11 {
    12     int c;
    13 public:
    14     void DerivedCommonFunction();
    15     void virtual VirtualFunction();
    16 };
    17 
    18 class DerivedClass2 : virtual public Base
    19 {
    20     int d;
    21 public:
    22     void DerivedCommonFunction();
    23     void virtual VirtualFunction();
    24 };
    25 
    26 class DerivedDerivedClass : public DerivedClass1, public DerivedClass2
    27 {
    28     int e;
    29 public:
    30     void DerivedDerivedCommonFunction();
    31     void virtual VirtualFunction();
    32 };
    class Base    size(16):
        +---
     0    | {vfptr}
     8    | a
    12    | b
        +---
    
    Base::$vftable@:
        | &Base_meta
        |  0
     0    | &Base::VirtualFunction
    
    Base::VirtualFunction this adjustor: 0
    
    class DerivedClass1    size(32):
        +---
     0    | {vbptr}
     8    | c
          | <alignment member> (size=4)
        +---
        +--- (virtual base Base)
    16    | {vfptr}
    24    | a
    28    | b
        +---
    
    DerivedClass1::$vbtable@:
     0    | 0
     1    | 16 (DerivedClass1d(DerivedClass1+0)Base)
    
    DerivedClass1::$vftable@:
        | -16
     0    | &DerivedClass1::VirtualFunction
    
    DerivedClass1::VirtualFunction this adjustor: 16
    vbi:       class  offset o.vbptr  o.vbte fVtorDisp      只要有虚继承(包括非直接继承中包含虚继承),就要这条
                Base      16       0       4 0
    
    class DerivedClass2    size(32):
        +---
     0    | {vbptr}
     8    | d
          | <alignment member> (size=4)
        +---
        +--- (virtual base Base)
    16    | {vfptr}
    24    | a
    28    | b
        +---
    
    DerivedClass2::$vbtable@:
     0    | 0
     1    | 16 (DerivedClass2d(DerivedClass2+0)Base)
    
    DerivedClass2::$vftable@:
        | -16
     0    | &DerivedClass2::VirtualFunction
    
    DerivedClass2::VirtualFunction this adjustor: 16
    vbi:       class  offset o.vbptr  o.vbte fVtorDisp
                Base      16       0       4 0
    
    class DerivedDerivedClass    size(56):
        +---
     0    | +--- (base class DerivedClass1)
     0    | | {vbptr}
     8    | | c
          | | <alignment member> (size=4)
        | +---
    16    | +--- (base class DerivedClass2)
    16    | | {vbptr}
    24    | | d
          | | <alignment member> (size=4)
        | +---
    32    | e
          | <alignment member> (size=4)
        +---
        +--- (virtual base Base)
    40    | {vfptr}
    48    | a
    52    | b
        +---
    
    DerivedDerivedClass::$vbtable@DerivedClass1@:            表示DerivedDerivedClass的一个$vbtable相对于DerivedClass1来说 
     0    | 0
     1    | 40 (DerivedDerivedClassd(DerivedClass1+0)Base)   其中40 = {vfptr} - {vbptr} = 40 - 0
    
    DerivedDerivedClass::$vbtable@DerivedClass2@:            表示DerivedDerivedClass的一个$vbtable相对于DerivedClass2来说   
     0    | 0
     1    | 24 (DerivedDerivedClassd(DerivedClass2+0)Base)   其中24 = {vfptr} - {vbptr} = 40 - 16
    
    DerivedDerivedClass::$vftable@:
        | -40
     0    | &DerivedDerivedClass::VirtualFunction
    
    DerivedDerivedClass::VirtualFunction this adjustor: 40
    vbi:       class  offset o.vbptr  o.vbte fVtorDisp       只要有虚继承(包括非直接继承中包含虚继承),就要这条
                Base      40       0       4 0

    一般继承+虚继承

     1 class Base
     2 {
     3     int a;
     4     int b;
     5 public:
     6     void CommonFunction();
     7     void virtual VirtualFunction();
     8 };
     9 
    10 class DerivedClass1 : public Base
    11 {
    12     int c;
    13 public:
    14     void DerivedCommonFunction();
    15     void virtual VirtualFunction();
    16 };
    17 
    18 class DerivedClass2 : public Base
    19 {
    20     int d;
    21 public:
    22     void DerivedCommonFunction();
    23     void virtual VirtualFunction();
    24 };
    25 
    26 class DerivedClass3 : virtual public Base
    27 {
    28     int m;
    29 public:
    30     void DerivedCommonFunction();
    31     void virtual VirtualFunction();
    32 };
    33 
    34 class DerivedClass4 : virtual public Base
    35 {
    36     int n;
    37 public:
    38     void DerivedCommonFunction();
    39     void virtual VirtualFunction();
    40 };
    41 
    42 class DerivedDerivedClass : public DerivedClass1, public DerivedClass2, public DerivedClass3, public DerivedClass4
    43 {
    44     int e;
    45 public:
    46     void DerivedDerivedCommonFunction();
    47     void virtual VirtualFunction();
    48 };
    class Base    size(16):
        +---
     0    | {vfptr}
     8    | a
    12    | b
        +---
    
    Base::$vftable@:
        | &Base_meta
        |  0
     0    | &Base::VirtualFunction
    
    Base::VirtualFunction this adjustor: 0
    
    class DerivedClass1    size(24):
        +---
     0    | +--- (base class Base)
     0    | | {vfptr}
     8    | | a
    12    | | b
        | +---
    16    | c
          | <alignment member> (size=4)
        +---
    
    DerivedClass1::$vftable@:
        | &DerivedClass1_meta
        |  0
     0    | &DerivedClass1::VirtualFunction
    
    DerivedClass1::VirtualFunction this adjustor: 0
    
    class DerivedClass2    size(24):
        +---
     0    | +--- (base class Base)
     0    | | {vfptr}
     8    | | a
    12    | | b
        | +---
    16    | d
          | <alignment member> (size=4)
        +---
    
    DerivedClass2::$vftable@:
        | &DerivedClass2_meta
        |  0
     0    | &DerivedClass2::VirtualFunction
    
    DerivedClass2::VirtualFunction this adjustor: 0
    
    class DerivedClass3    size(32):
        +---
     0    | {vbptr}
     8    | m
          | <alignment member> (size=4)
        +---
        +--- (virtual base Base)
    16    | {vfptr}
    24    | a
    28    | b
        +---
    
    DerivedClass3::$vbtable@:
     0    | 0
     1    | 16 (DerivedClass3d(DerivedClass3+0)Base)
    
    DerivedClass3::$vftable@:
        | -16
     0    | &DerivedClass3::VirtualFunction
    
    DerivedClass3::VirtualFunction this adjustor: 16
    vbi:       class  offset o.vbptr  o.vbte fVtorDisp
                Base      16       0       4 0
    
    class DerivedClass4    size(32):
        +---
     0    | {vbptr}
     8    | n
          | <alignment member> (size=4)
        +---
        +--- (virtual base Base)
    16    | {vfptr}
    24    | a
    28    | b
        +---
    
    DerivedClass4::$vbtable@:
     0    | 0
     1    | 16 (DerivedClass4d(DerivedClass4+0)Base)
    
    DerivedClass4::$vftable@:
        | -16
     0    | &DerivedClass4::VirtualFunction
    
    DerivedClass4::VirtualFunction this adjustor: 16
    vbi:       class  offset o.vbptr  o.vbte fVtorDisp
                Base      16       0       4 0
    
    class DerivedDerivedClass    size(104):
        +---
     0    | +--- (base class DerivedClass1)
     0    | | +--- (base class Base)
     0    | | | {vfptr}
     8    | | | a
    12    | | | b
        | | +---
    16    | | c
          | | <alignment member> (size=4)
        | +---
    24    | +--- (base class DerivedClass2)
    24    | | +--- (base class Base)
    24    | | | {vfptr}
    32    | | | a
    36    | | | b
        | | +---
    40    | | d
          | | <alignment member> (size=4)
        | +---
    48    | +--- (base class DerivedClass3)
    48    | | {vbptr}
    56    | | m
          | | <alignment member> (size=4)
        | +---
    64    | +--- (base class DerivedClass4)
    64    | | {vbptr}
    72    | | n
          | | <alignment member> (size=4)
        | +---
    80    | e
          | <alignment member> (size=4)
        +---
        +--- (virtual base Base)
    88    | {vfptr}
    96    | a
    100    | b
        +---
    
    DerivedDerivedClass::$vftable@DerivedClass1@:
        | &DerivedDerivedClass_meta
        |  0
     0    | &DerivedDerivedClass::VirtualFunction
    
    DerivedDerivedClass::$vftable@DerivedClass2@:
        | -24
     0    | &thunk: this-=24; goto DerivedDerivedClass::VirtualFunction
    
    DerivedDerivedClass::$vbtable@DerivedClass3@:
     0    | 0
     1    | 40 (DerivedDerivedClassd(DerivedClass3+0)Base)
    
    DerivedDerivedClass::$vbtable@DerivedClass4@:
     0    | 0
     1    | 24 (DerivedDerivedClassd(DerivedClass4+0)Base)
    
    DerivedDerivedClass::$vftable@DerivedClass3@:
        | -88
     0    | &thunk: this-=88; goto DerivedDerivedClass::VirtualFunction
    
    DerivedDerivedClass::VirtualFunction this adjustor: 0
    vbi:       class  offset o.vbptr  o.vbte fVtorDisp             只要有虚继承(包括非直接继承中包含虚继承),就要这条      offset表示vftable所在偏移    o.vbptr表示选中的vbtable的指针(这边指向DerivedClass3)
                Base      88      48       4 0                     这边的Base是指我们申明的Base积累

    虚继承+一般继承

    1 class DerivedDerivedClass : public DerivedClass3, public DerivedClass4, public DerivedClass1, public DerivedClass2

    结果同 一般继承+虚继承  表明结果跟继承顺序没关系

    一般继承和虚继承混用1

     1 class Base
     2 {
     3     int a;
     4     int b;
     5 public:
     6     void CommonFunction();
     7     void virtual VirtualFunction();
     8 };
     9 
    10 class DerivedClass1 : public Base
    11 {
    12     int c;
    13 public:
    14     void DerivedCommonFunction();
    15     void virtual VirtualFunction();
    16 };
    17 
    18 class DerivedClass2 : public Base
    19 {
    20     int d;
    21 public:
    22     void DerivedCommonFunction();
    23     void virtual VirtualFunction();
    24 };
    25 
    26 class DerivedClass3 : virtual public Base
    27 {
    28     int m;
    29 public:
    30     void DerivedCommonFunction();
    31     void virtual VirtualFunction();
    32 };
    33 
    34 class DerivedClass4 : virtual public Base
    35 {
    36     int n;
    37 public:
    38     void DerivedCommonFunction();
    39     void virtual VirtualFunction();
    40 };
    41 
    42 class DerivedDerivedClass : virtual public DerivedClass1, virtual public DerivedClass2, virtual public DerivedClass3, virtual public DerivedClass4
    43 {
    44     int e;
    45 public:
    46     void DerivedDerivedCommonFunction();
    47     void virtual VirtualFunction();
    48 };
    class Base    size(16):
        +---
     0    | {vfptr}
     8    | a
    12    | b
        +---
    
    Base::$vftable@:
        | &Base_meta
        |  0
     0    | &Base::VirtualFunction
    
    Base::VirtualFunction this adjustor: 0
    
    class DerivedClass1    size(24):
        +---
     0    | +--- (base class Base)
     0    | | {vfptr}
     8    | | a
    12    | | b
        | +---
    16    | c
          | <alignment member> (size=4)
        +---
    
    DerivedClass1::$vftable@:
        | &DerivedClass1_meta
        |  0
     0    | &DerivedClass1::VirtualFunction
    
    DerivedClass1::VirtualFunction this adjustor: 0
    
    class DerivedClass2    size(24):
        +---
     0    | +--- (base class Base)
     0    | | {vfptr}
     8    | | a
    12    | | b
        | +---
    16    | d
          | <alignment member> (size=4)
        +---
    
    DerivedClass2::$vftable@:
        | &DerivedClass2_meta
        |  0
     0    | &DerivedClass2::VirtualFunction
    
    DerivedClass2::VirtualFunction this adjustor: 0
    
    class DerivedClass3    size(32):
        +---
     0    | {vbptr}
     8    | m
          | <alignment member> (size=4)
        +---
        +--- (virtual base Base)
    16    | {vfptr}
    24    | a
    28    | b
        +---
    
    DerivedClass3::$vbtable@:
     0    | 0
     1    | 16 (DerivedClass3d(DerivedClass3+0)Base)
    
    DerivedClass3::$vftable@:
        | -16
     0    | &DerivedClass3::VirtualFunction
    
    DerivedClass3::VirtualFunction this adjustor: 16
    vbi:       class  offset o.vbptr  o.vbte fVtorDisp
                Base      16       0       4 0
    
    class DerivedClass4    size(32):
        +---
     0    | {vbptr}
     8    | n
          | <alignment member> (size=4)
        +---
        +--- (virtual base Base)
    16    | {vfptr}
    24    | a
    28    | b
        +---
    
    DerivedClass4::$vbtable@:
     0    | 0
     1    | 16 (DerivedClass4d(DerivedClass4+0)Base)
    
    DerivedClass4::$vftable@:
        | -16
     0    | &DerivedClass4::VirtualFunction
    
    DerivedClass4::VirtualFunction this adjustor: 16
    vbi:       class  offset o.vbptr  o.vbte fVtorDisp
                Base      16       0       4 0
    
    class DerivedDerivedClass    size(112):
        +---
     0    | {vbptr}
     8    | e
          | <alignment member> (size=4)
        +---
        +--- (virtual base DerivedClass1)
    16    | +--- (base class Base)
    16    | | {vfptr}
    24    | | a
    28    | | b
        | +---
    32    | c
          | <alignment member> (size=4)
        +---
        +--- (virtual base DerivedClass2)
    40    | +--- (base class Base)
    40    | | {vfptr}
    48    | | a
    52    | | b
        | +---
    56    | d
          | <alignment member> (size=4)
        +---
        +--- (virtual base Base)
    64    | {vfptr}
    72    | a
    76    | b
        +---
        +--- (virtual base DerivedClass3)
    80    | {vbptr}
    88    | m
          | <alignment member> (size=4)
        +---
        +--- (virtual base DerivedClass4)
    96    | {vbptr}
    104    | n
          | <alignment member> (size=4)
        +---
    
    DerivedDerivedClass::$vbtable@DerivedDerivedClass@:                       表示有5个虚继承类(包括非直接继承中包含虚继承类) 第二列指明类所在位置
     0    | 0
     1    | 16 (DerivedDerivedClassd(DerivedDerivedClass+0)DerivedClass1)
     2    | 40 (DerivedDerivedClassd(DerivedDerivedClass+0)DerivedClass2)
     3    | 64 (DerivedDerivedClassd(DerivedDerivedClass+0)Base)
     4    | 80 (DerivedDerivedClassd(DerivedDerivedClass+0)DerivedClass3)
     5    | 96 (DerivedDerivedClassd(DerivedDerivedClass+0)DerivedClass4)
    
    DerivedDerivedClass::$vftable@DerivedClass1@:       DerivedClass1类本身申明为非虚继承,所以才有这| -16
     0    | &DerivedDerivedClass::VirtualFunction
    
    DerivedDerivedClass::$vftable@DerivedClass2@:       DerivedClass2类本身申明为非虚继承,所以才有这个
        | -40
     0    | &thunk: this-=24; goto DerivedDerivedClass::VirtualFunction
    
    DerivedDerivedClass::$vftable@DerivedClass3@:       DerivedClass3类本身和DerivedClass4类本身申明为虚继承,所以才公用一个
        | -64
     0    | &thunk: this-=48; goto DerivedDerivedClass::VirtualFunction
    
    DerivedDerivedClass::$vbtable@DerivedClass3@:       DerivedClass3类本身申明为虚继承,所以才有这个
     0    | 0
     1    | -16 (DerivedDerivedClassd(DerivedClass3+0)Base)
    
    DerivedDerivedClass::$vbtable@DerivedClass4@:     DerivedClass4类本身申明为虚继承,所以才有这个
     0    | 0
     1    | -32 (DerivedDerivedClassd(DerivedClass4+0)Base)
    
    DerivedDerivedClass::VirtualFunction this adjustor: 16
    vbi:       class  offset o.vbptr  o.vbte fVtorDisp        o.vbte表示vb的table entry,参见DerivedDerivedClass::$vbtable@DerivedDerivedClass@
       DerivedClass1      16       0       4 0
       DerivedClass2      40       0       8 0
                Base      64       0      12 0
       DerivedClass3      80       0      16 0
       DerivedClass4      96       0      20 0

    一般继承和虚继承混用2

     1 class Base
     2 {
     3     int a;
     4     int b;
     5 public:
     6     void CommonFunction();
     7     void virtual VirtualFunction();
     8 };
     9 
    10 class DerivedClass1 : public Base
    11 {
    12     int c;
    13 public:
    14     void DerivedCommonFunction();
    15     void virtual VirtualFunction();
    16 };
    17 
    18 class DerivedClass2 : public Base
    19 {
    20     int d;
    21 public:
    22     void DerivedCommonFunction();
    23     void virtual VirtualFunction();
    24 };
    25 
    26 class DerivedClass3 : virtual public Base
    27 {
    28     int m;
    29 public:
    30     void DerivedCommonFunction();
    31     void virtual VirtualFunction();
    32 };
    33 
    34 class DerivedClass4 : virtual public Base
    35 {
    36     int n;
    37 public:
    38     void DerivedCommonFunction();
    39     void virtual VirtualFunction();
    40 };
    41 
    42 class DerivedDerivedClass : virtual public DerivedClass1, virtual public DerivedClass2, public DerivedClass3, public DerivedClass4
    43 {
    44     int e;
    45 public:
    46     void DerivedDerivedCommonFunction();
    47     void virtual VirtualFunction();
    48 };
    class Base    size(16):
        +---
     0    | {vfptr}
     8    | a
    12    | b
        +---
    
    Base::$vftable@:
        | &Base_meta
        |  0
     0    | &Base::VirtualFunction
    
    Base::VirtualFunction this adjustor: 0
    
    class DerivedClass1    size(24):
        +---
     0    | +--- (base class Base)
     0    | | {vfptr}
     8    | | a
    12    | | b
        | +---
    16    | c
          | <alignment member> (size=4)
        +---
    
    DerivedClass1::$vftable@:
        | &DerivedClass1_meta
        |  0
     0    | &DerivedClass1::VirtualFunction
    
    DerivedClass1::VirtualFunction this adjustor: 0
    
    class DerivedClass2    size(24):
        +---
     0    | +--- (base class Base)
     0    | | {vfptr}
     8    | | a
    12    | | b
        | +---
    16    | d
          | <alignment member> (size=4)
        +---
    
    DerivedClass2::$vftable@:
        | &DerivedClass2_meta
        |  0
     0    | &DerivedClass2::VirtualFunction
    
    DerivedClass2::VirtualFunction this adjustor: 0
    
    class DerivedClass3    size(32):
        +---
     0    | {vbptr}
     8    | m
          | <alignment member> (size=4)
        +---
        +--- (virtual base Base)
    16    | {vfptr}
    24    | a
    28    | b
        +---
    
    DerivedClass3::$vbtable@:
     0    | 0
     1    | 16 (DerivedClass3d(DerivedClass3+0)Base)
    
    DerivedClass3::$vftable@:
        | -16
     0    | &DerivedClass3::VirtualFunction
    
    DerivedClass3::VirtualFunction this adjustor: 16
    vbi:       class  offset o.vbptr  o.vbte fVtorDisp
                Base      16       0       4 0
    
    class DerivedClass4    size(32):
        +---
     0    | {vbptr}
     8    | n
          | <alignment member> (size=4)
        +---
        +--- (virtual base Base)
    16    | {vfptr}
    24    | a
    28    | b
        +---
    
    DerivedClass4::$vbtable@:
     0    | 0
     1    | 16 (DerivedClass4d(DerivedClass4+0)Base)
    
    DerivedClass4::$vftable@:
        | -16
     0    | &DerivedClass4::VirtualFunction
    
    DerivedClass4::VirtualFunction this adjustor: 16
    vbi:       class  offset o.vbptr  o.vbte fVtorDisp
                Base      16       0       4 0
    
    class DerivedDerivedClass    size(104):
        +---
     0    | +--- (base class DerivedClass3)
     0    | | {vbptr}
     8    | | m
          | | <alignment member> (size=4)
        | +---
    16    | +--- (base class DerivedClass4)
    16    | | {vbptr}
    24    | | n
          | | <alignment member> (size=4)
        | +---
    32    | e
          | <alignment member> (size=4)
        +---
        +--- (virtual base DerivedClass1)
    40    | +--- (base class Base)
    40    | | {vfptr}
    48    | | a
    52    | | b
        | +---
    56    | c
          | <alignment member> (size=4)
        +---
        +--- (virtual base DerivedClass2)
    64    | +--- (base class Base)
    64    | | {vfptr}
    72    | | a
    76    | | b
        | +---
    80    | d
          | <alignment member> (size=4)
        +---
        +--- (virtual base Base)
    88    | {vfptr}
    96    | a
    100    | b
        +---
    
    DerivedDerivedClass::$vbtable@DerivedClass3@:
     0    | 0
     1    | 88 (DerivedDerivedClassd(DerivedClass3+0)Base)
     2    | 40 (DerivedDerivedClassd(DerivedDerivedClass+0)DerivedClass1)
     3    | 64 (DerivedDerivedClassd(DerivedDerivedClass+0)DerivedClass2)
    
    DerivedDerivedClass::$vbtable@DerivedClass4@:
     0    | 0
     1    | 72 (DerivedDerivedClassd(DerivedClass4+0)Base)
    
    DerivedDerivedClass::$vftable@DerivedClass1@:
        | -40
     0    | &DerivedDerivedClass::VirtualFunction
    
    DerivedDerivedClass::$vftable@DerivedClass2@:
        | -64
     0    | &thunk: this-=24; goto DerivedDerivedClass::VirtualFunction
    
    DerivedDerivedClass::$vftable@DerivedClass3@:
        | -88
     0    | &thunk: this-=48; goto DerivedDerivedClass::VirtualFunction
    
    DerivedDerivedClass::VirtualFunction this adjustor: 40
    vbi:       class  offset o.vbptr  o.vbte fVtorDisp
       DerivedClass1      40       0       8 0
       DerivedClass2      64       0      12 0
                Base      88       0       4 0

    https://www.cnblogs.com/jlxuexijidi-2015/p/5293617.html   virtual成员函数

  • 相关阅读:
    2013 HIT 春季校赛C题
    2013610 四省赛
    [BZOJ] 1441 Min
    移植中Makefile学习 关键字理解
    Emgu 学习之HelloWorld
    XML 基本概念和XPath选择
    AI 资源帖
    c语言 static
    Linux watch命令 实时监测命令的运行结果(转)
    ctags 注意点
  • 原文地址:https://www.cnblogs.com/spriteflk/p/13432463.html
Copyright © 2011-2022 走看看