Object layout in case of virtual functions and multiple inheritance

前端 未结 4 705
醉酒成梦
醉酒成梦 2020-11-30 00:07

I was recently asked in an interview about object layout with virtual functions and multiple inheritance involved.
I explained it in context of how it is implemented wit

4条回答
  •  生来不讨喜
    2020-11-30 00:53

    The memory layout and the vtable layout depend on your compiler. Using my gcc for instance, they look like this:

    sizeof(int) == 4
    sizeof(A) == 8
    sizeof(B) == 8
    sizeof(C) == 20
    

    Note that sizeof(int) and the space needed for the vtable pointer can also vary from compiler to compiler and platform to platform. The reason why sizeof(C) == 20 and not 16 is that gcc gives it 8 bytes for the A subobject, 8 bytes for the B subobject and 4 bytes for its member int c.

    Vtable for C
    C::_ZTV1C: 6u entries
    0     (int (*)(...))0
    4     (int (*)(...))(& _ZTI1C)
    8     A::funA
    12    (int (*)(...))-0x00000000000000008
    16    (int (*)(...))(& _ZTI1C)
    20    B::funB
    
    Class C
       size=20 align=4
       base size=20 base align=4
    C (0x40bd5e00) 0
        vptr=((& C::_ZTV1C) + 8u)
      A (0x40bd6080) 0
          primary-for C (0x40bd5e00)
      B (0x40bd60c0) 8
          vptr=((& C::_ZTV1C) + 20u)
    

    Using virtual inheritance

    class C : public virtual A, public virtual B
    

    the layout changes to

    Vtable for C
    C::_ZTV1C: 12u entries
    0     16u
    4     8u
    8     (int (*)(...))0
    12    (int (*)(...))(& _ZTI1C)
    16    0u
    20    (int (*)(...))-0x00000000000000008
    24    (int (*)(...))(& _ZTI1C)
    28    A::funA
    32    0u
    36    (int (*)(...))-0x00000000000000010
    40    (int (*)(...))(& _ZTI1C)
    44    B::funB
    
    VTT for C
    C::_ZTT1C: 3u entries
    0     ((& C::_ZTV1C) + 16u)
    4     ((& C::_ZTV1C) + 28u)
    8     ((& C::_ZTV1C) + 44u)
    
    Class C
       size=24 align=4
       base size=8 base align=4
    C (0x40bd5e00) 0
        vptridx=0u vptr=((& C::_ZTV1C) + 16u)
      A (0x40bd6080) 8 virtual
          vptridx=4u vbaseoffset=-0x0000000000000000c vptr=((& C::_ZTV1C) + 28u)
      B (0x40bd60c0) 16 virtual
          vptridx=8u vbaseoffset=-0x00000000000000010 vptr=((& C::_ZTV1C) + 44u)
    
    

    Using gcc, you can add -fdump-class-hierarchy to obtain this information.

提交回复
热议问题