gpt4 book ai didi

C++Day12虚拟继承内存布局测试

转载 作者:我是一只小鸟 更新时间:2023-01-26 22:31:06 25 4
gpt4 key购买 nike

测试1、虚继承与继承的区别 。

                          
                            1.1
                          
                          
                              单个继承,不带虚函数

                          
                          
                            1
                          
                          >
                          
                            class
                          
                           B    size(
                          
                            8
                          
                          
                            ):

                          
                          
                            1
                          
                          >    +---

                          
                            1
                          
                          > 
                          
                            0
                          
                              | +--- (
                          
                            base
                          
                          
                            class
                          
                          
                             A)

                          
                          
                            1
                          
                          > 
                          
                            0
                          
                              | | _ia                       
                          
                            //
                          
                          
                            4B
                          
                          
                            1
                          
                          >    | +---

                          
                            1
                          
                          > 
                          
                            4
                          
                              | _ib                        
                          
                            //
                          
                          
                            4B
                          
                        

有两个int类型数据成员,占8B,基类逻辑存在前面 。

                          
                            1.2
                          
                          
                            、单个虚继承,不带虚函数

                          
                          
                            1
                          
                          >
                          
                            class
                          
                           B    size(
                          
                            12
                          
                          
                            ):

                          
                          
                            1
                          
                          >    +---

                          
                            1
                          
                          > 
                          
                            0
                          
                              | {vbptr}        
                          
                            //
                          
                          
                            虚基指针(指向虚基表)
                          
                          
                            1
                          
                          > 
                          
                            4
                          
                              | _ib                          
                          
                            //
                          
                          
                            派生类放到前面
                          
                          
                            1
                          
                          >    +---

                          
                            1
                          
                          >    +--- (
                          
                            virtual
                          
                          
                            base
                          
                           A)        
                          
                            //
                          
                          
                            虚基类
                          
                          
                            1
                          
                          > 
                          
                            8
                          
                              |
                          
                             _ia

                          
                          
                            1
                          
                          >    +---

                          
                            1
                          
                          >B::$vbtable@:                     
                          
                            //
                          
                          
                            虚基表
                          
                          
                            1
                          
                          > 
                          
                            0
                          
                              | 
                          
                            0
                          
                          
                            // 虚基指针距离派生类对象偏移0B

                          
                          
                            1
                          
                          > 
                          
                            1
                          
                              | 
                          
                            8
                          
                           (Bd(B+
                          
                            0
                          
                          )A)            
                          
                            //  虚基指针向下偏移8B找到虚基类
                          
                          
                            

虚继承多一个虚基指针,共12B,虚拟继承会将派生类的逻辑存到前面; 。

虚基表中存放的内容:(1)虚基指针距离派生类对象首地址的偏移信息(2)虚基类的偏移信息 。

  测试2、单个虚继承,带虚函数 。

                          
                            2.1
                          
                          
                            、单个
                             继承 
                            ,带
                             虚函数 
                          
                          
                            1
                          
                          >
                          
                            class
                          
                           B    size(
                          
                            12
                          
                          
                            ):

                          
                          
                            1
                          
                          >    +---

                          
                            1
                          
                          > 
                          
                            0
                          
                              | +--- (
                          
                            base
                          
                          
                            class
                          
                          
                             A)

                          
                          
                            1
                          
                          > 
                          
                            0
                          
                              | | {vfptr}       
                          
                            //
                          
                          
                            虚函数指针
                          
                          
                            1
                          
                          > 
                          
                            4
                          
                              | |
                          
                             _ia

                          
                          
                            1
                          
                          >    | +---

                          
                            1
                          
                          > 
                          
                            8
                          
                              |
                          
                             _ib

                          
                          
                            1
                          
                          >    +---

                          
                            1
                          
                          >B::$vftable@:              
                          
                            //
                          
                          
                            虚表
                          
                          
                            1
                          
                          >    | &
                          
                            B_meta

                          
                          
                            1
                          
                          >    |  
                          
                            0
                          
                          
                            1
                          
                          > 
                          
                            0
                          
                              | &B::f                      
                          
                            //
                          
                          
                             f 和 fb2 入虚表,fb不是虚函数,不入虚表
                          
                          
                            1
                          
                          > 
                          
                            1
                          
                              | &B::fb2                   
                          
                            //
                          
                          
                             派生类新增虚函数直接放在基类虚表中
                          
                        

带虚函数的话,多一个虚函数指针,指向虚表,所以共占12B,派生类新增的虚函数放入基类虚表 。

                          
                            2.3
                          
                          
                            、单个
                             虚继承 
                            ,带
                             虚函数 
                            ,派生类
                             不新增 
                          
                          
                            8
                          
                          /
                          
                            16
                          
                          
                            1
                          
                          >
                          
                            class
                          
                           B    size(
                          
                            16
                          
                          
                            ):

                          
                          
                            1
                          
                          >    +---

                          
                            1
                          
                          > 
                          
                            0
                          
                              | {vbptr}    
                          
                            //
                          
                          
                            有虚继承的时候就多一个虚基指针,虚基指针指向虚基表  
                          
                          
                            1
                          
                          > 
                          
                            4
                          
                              | _ib        
                          
                            //
                          
                          
                            有虚函数的时候就产生一个虚函数指针,虚函数指针指向虚函数表
                          
                          
                            1
                          
                          >    +--- 

                          
                            1
                          
                          >    +--- (
                          
                            virtual
                          
                          
                            base
                          
                          
                             A)

                          
                          
                             1 
                            > 
                             8 
                                |
                             {vfptr} 
                          
                          
                            1
                          
                          >
                          
                            12
                          
                              |
                          
                             _ia

                          
                          
                            1
                          
                          >    +---

                          
                            1
                          
                          >
                          
                            B::$vbtable@:  //虚基表

                          
                          
                            1
                          
                          > 
                          
                            0
                          
                              | 
                          
                            0                   // 虚基指针距离派生类对象偏移0B
                          
                          
                            1
                          
                          > 
                          
                            1
                          
                              | 
                          
                            8
                          
                           (Bd(B+
                          
                            0
                          
                          
                            )A)        // 虚基指针向下偏移8B找到虚基类

                          
                          
                            1
                          
                          >
                          
                            B::$vftable@:   //虚函数表

                          
                          
                            1
                          
                          >    | -
                          
                            8         
                          
                          
                            1
                          
                          > 
                          
                            0
                          
                              | &B::f
                        

两个 int 型变量,一个虚函数指针,一个虚基指针,共占16B; 。

虚拟继承使得派生类逻辑存在基类前面; 。

(虚拟继承后,基类在派生类后面,虚函数指针也在下面,派生类要找到虚函数表,向后偏移8B) 。

                          
                            2.2
                          
                          
                             单个
                             虚继承 
                            ,带
                             虚函数 
                             (自己
                             新增 
                          
                            1
                          
                          >
                          
                            class
                          
                           B    size(
                          
                            20
                          
                          
                            ):

                          
                          
                            1
                          
                          >    +---

                          
                            1
                          
                          > 
                          
                            0
                          
                              | {vfptr}    
                          
                            //
                          
                          
                            虚函数指针
                          
                          
                            1
                          
                          > 
                          
                            4
                          
                              | {vbptr}    
                          
                            //
                          
                          
                            虚基指针  (虚继承多一个)  {虚拟继承,派生类在前面}
                          
                          
                            1
                          
                          > 
                          
                            8
                          
                              |
                          
                             _ib

                          
                          
                            1
                          
                          >    +---

                          
                            1
                          
                          >    +--- (
                          
                            virtual
                          
                          
                            base
                          
                          
                             A)    

                          
                          
                            1
                          
                          >
                          
                            12
                          
                              | {vfptr}           
                          
                            //
                          
                          
                            虚函数指针
                          
                          
                            1
                          
                          >
                          
                            16
                          
                              |
                          
                             _ia

                          
                          
                            1
                          
                          >    +---

                          
                            1
                          
                          >B::$vftable@B@:        
                          
                            //
                          
                          
                            虚表
                          
                          
                            1
                          
                          >    | &
                          
                            B_meta

                          
                          
                            1
                          
                          >    |  
                          
                            0
                          
                          
                            1
                          
                          > 
                          
                            0
                          
                              | &B::fb2     
                          
                            //
                          
                          
                            派生类新增虚函数,放在最前面,访问新增虚函数快一些,不用偏移 ,多一个虚函数指针,指向新的虚表
                          
                          
                            1
                          
                          >B::$vbtable@:                     
                          
                            //
                          
                          
                            虚基表
                          
                          
                            1
                          
                          > 
                          
                            0
                          
                              | -
                          
                            4
                          
                                                 /
                          
                            /
                          
                          
                            虚基指针距离派生类对象首地址的偏移信息
                          
                          
                            1
                          
                          > 
                          
                            1
                          
                              | 
                          
                            8
                          
                           (Bd(B+
                          
                            4
                          
                          )A)            
                          
                            //
                          
                          
                            找到虚基类的偏移信息
                          
                          
                            1
                          
                          >B::$vftable@A@:                
                          
                            //
                          
                          
                            虚表
                          
                          
                            1
                          
                          >    | -
                          
                            12
                          
                          
                            1
                          
                          > 
                          
                            0
                          
                              | &B::f    基类布局在最后面
                        

派生类中新增一个虚函数指针,指向一张新的虚表,存放派生类新增的虚函数,可以更快的访问到 。

所以,两个虚函数指针,一个虚基指针,两个int类型变量,共20B 。

  。

  。

  。

 测试三:多重继承(带虚函数) 。

                          
                            3.1
                          
                           普通 
                            多重
                             继承 
                            ,带虚函数,自己
                             有新增 
                            虚函数

                          
                          
                            28   //Base1中 f() g() h() , Base2中 f() g() h() , Base3中 f() g() h() Derived 中 f() g1() 
                          
                          
                            1
                          
                          >
                          
                            class
                          
                           Derived    size(
                          
                            28
                          
                          
                            ):

                          
                          
                            1
                          
                          >    +---

                          
                            1
                          
                          > 
                          
                            0
                          
                              | +--- (
                          
                            base
                          
                          
                            class
                          
                           Base1)            
                          
                            //
                          
                          
                            基类有自己的虚函数表,基类的布局按照被继承时的顺序排列
                          
                          
                            1
                          
                          > 
                          
                            0
                          
                              | | {vfptr}                         
                          
                            // 
                          
                          
                            3个虚函数指针指向不同虚表
                          
                          
                            1
                          
                          > 
                          
                            4
                          
                              | |
                          
                             _iBase1

                          
                          
                            1
                          
                          >    | +---

                          
                            1
                          
                          > 
                          
                            8
                          
                              | +--- (
                          
                            base
                          
                          
                            class
                          
                          
                             Base2)

                          
                          
                            1
                          
                          > 
                          
                            8
                          
                              | |
                          
                             {vfptr}

                          
                          
                            1
                          
                          >
                          
                            12
                          
                              | |
                          
                             _iBase2

                          
                          
                            1
                          
                          >    | +---

                          
                            1
                          
                          >
                          
                            16
                          
                              | +--- (
                          
                            base
                          
                          
                            class
                          
                          
                             Base3)

                          
                          
                            1
                          
                          >
                          
                            16
                          
                              | |
                          
                             {vfptr}

                          
                          
                            1
                          
                          >
                          
                            20
                          
                              | |
                          
                             _iBase3

                          
                          
                            1
                          
                          >    | +---

                          
                            1
                          
                          >
                          
                            24
                          
                              |
                          
                             _iDerived

                          
                          
                            1
                          
                          >    +---

                          
                            1
                          
                          >
                          
                            Derived::$vftable@Base1@:

                          
                          
                            1
                          
                          >    | &
                          
                            Derived_meta

                          
                          
                            1
                          
                          >    |  
                          
                            0
                          
                          
                            1
                          
                          > 
                          
                            0
                          
                              | &Derived::f(虚函数的覆盖)    
                          
                            //
                          
                          
                            第一个虚函数表中存放真实的被覆盖的虚函数地址,其他虚函数表中存放跳转地址
                          
                          
                            1
                          
                          > 
                          
                            1
                          
                              | &
                          
                            Base1::g

                          
                          
                            1
                          
                          > 
                          
                            2
                          
                              | &
                          
                            Base1::h

                          
                          
                            1
                          
                          > 
                          
                            3
                          
                              | &
                          
                            Derived::g1        (新的虚函数,直接放在基类之后,加快查找速度)

                          
                          
                            1
                          
                          >
                          
                            Derived::$vftable@Base2@:

                          
                          
                            1
                          
                          >    | -
                          
                            8
                          
                          
                            1
                          
                          > 
                          
                            0
                          
                              | &thunk: 
                          
                            this
                          
                          -=
                          
                            8
                          
                          ; 
                          
                            goto
                          
                           Derived::f   
                          
                            //
                          
                          
                            虚函数表还可以存放跳转指令
                          
                          
                            1
                          
                          > 
                          
                            1
                          
                              | &
                          
                            Base2::g

                          
                          
                            1
                          
                          > 
                          
                            2
                          
                              | &
                          
                            Base2::h

                          
                          
                            1
                          
                          >
                          
                            Derived::$vftable@Base3@:

                          
                          
                            1
                          
                          >    | -
                          
                            16
                          
                          
                            1
                          
                          > 
                          
                            0
                          
                              | &thunk: 
                          
                            this
                          
                          -=
                          
                            16
                          
                          ; 
                          
                            goto
                          
                          
                             Derived::f

                          
                          
                            1
                          
                          > 
                          
                            1
                          
                              | &
                          
                            Base3::g

                          
                          
                            1
                          
                          > 
                          
                            2
                          
                              | &Base3::h
                        

Base1、Base2、Base3中各有一个虚函数指针指向自己的虚表,有4个int类型的数据成员,共占28B 。

第一个虚函数表中存放真实的被覆盖的虚函数地址,其他虚函数表中存放跳转地址 。

                          
                            3.2
                          
                          
                            、虚拟多重继承,带虚函数,自己有新增虚函数(只有第一个是虚继承)

                          
                          
                            32  Base1是虚继承
                          
                          
                            1
                          
                          >
                          
                            class
                          
                           Derived    size(
                          
                            32
                          
                          ):    
                          
                            //
                          
                          
                            多一个虚基指针
                          
                          
                            1
                          
                          >    +---

                          
                            1
                          
                          > 
                          
                            0
                          
                              | +--- (
                          
                            base
                          
                          
                            class
                          
                          
                             Base2)

                          
                          
                            1
                          
                          > 
                          
                            0
                          
                              | |
                          
                             {
                             vfptr 
                            }

                          
                          
                            1
                          
                          > 
                          
                            4
                          
                              | |
                          
                             _iBase2

                          
                          
                            1
                          
                          >    | +---

                          
                            1
                          
                          > 
                          
                            8
                          
                              | +--- (
                          
                            base
                          
                          
                            class
                          
                          
                             Base3)

                          
                          
                            1
                          
                          > 
                          
                            8
                          
                              | |
                          
                             {
                             vfptr 
                            }

                          
                          
                            1
                          
                          >
                          
                            12
                          
                              | |
                          
                             _iBase3

                          
                          
                            1
                          
                          >    | +---

                          
                            1
                          
                          >
                          
                            16
                          
                              |
                          
                             {
                             vbptr 
                            }

                          
                          
                            1
                          
                          >
                          
                            20
                          
                              |
                          
                             _iDerived

                          
                          
                            1
                          
                          >    +---

                          
                            1
                          
                          >    +--- (
                          
                            virtual
                          
                          
                            base
                          
                          
                             Base1)

                          
                          
                            1
                          
                          >
                          
                            24
                          
                              |
                          
                             {
                             vfptr 
                            }

                          
                          
                            1
                          
                          >
                          
                            28
                          
                              |
                          
                             _iBase1

                          
                          
                            1
                          
                          >    +---

                          
                            1
                          
                          >
                          
                            Derived::$
                             vftable 
                            @Base2@:

                          
                          
                            1
                          
                          >    | &
                          
                            Derived_meta

                          
                          
                            1
                          
                          >    |  
                          
                            0
                          
                          
                            1
                          
                          > 
                          
                            0
                          
                              | &
                          
                            Derived::f    //第一个虚函数表中存放真实的被覆盖的虚函数地址,其他虚函数表中存放跳转地址

                          
                          
                            1
                          
                          > 
                          
                            1
                          
                              | &
                          
                            Base2::g

                          
                          
                            1
                          
                          > 
                          
                            2
                          
                              | &
                          
                            Base2::h

                          
                          
                            1
                          
                          > 
                          
                            3
                          
                              | &
                          
                            Derived::g1

                          
                          
                            1
                          
                          >
                          
                            Derived::$
                             vftable 
                            @Base3@:

                          
                          
                            1
                          
                          >    | -
                          
                            8
                          
                          
                            //
                          
                          
                            去找Derived::f
                          
                          
                            1
                          
                          > 
                          
                            0
                          
                              | &thunk: 
                          
                            this
                          
                          -=
                          
                            8
                          
                          ; 
                          
                            goto
                          
                          
                             Derived::f

                          
                          
                            1
                          
                          > 
                          
                            1
                          
                              | &
                          
                            Base3::g

                          
                          
                            1
                          
                          > 
                          
                            2
                          
                              | &
                          
                            Base3::h

                          
                          
                            1
                          
                          >Derived::$
                          
                            vbtable
                          
                          @:   
                          
                            //
                          
                          
                            虚基表
                          
                          
                            1
                          
                          > 
                          
                            0
                          
                              | -
                          
                            16
                          
                          
                            1
                          
                          > 
                          
                            1
                          
                              | 
                          
                            8
                          
                           (Derivedd(Derived+
                          
                            16
                          
                          
                            )Base1)

                          
                          
                            1
                          
                          >
                          
                            Derived::$
                             vftable 
                            @Base1@:

                          
                          
                            1
                          
                          >    | -
                          
                            24
                          
                          
                            1
                          
                          > 
                          
                            0
                          
                              | &thunk: 
                          
                            this
                          
                          -=
                          
                            24
                          
                          ; 
                          
                            goto
                          
                          
                             Derived::f

                          
                          
                            1
                          
                          > 
                          
                            1
                          
                              | &
                          
                            Base1::g

                          
                          
                            1
                          
                          > 
                          
                            2
                          
                              | &Base1::h
                        

虚拟继承会将派生类的逻辑存到前面,Base1是虚继承,所以内存中的存放顺序为 Base2、Base3、Derived、Base1 。

所占空间大小,在上面一个例子基础上,多一个虚基指针,所以占32B 。

虚基指针向上偏移16B得到派生类对象首地址,向下偏移8B找到虚基类 。

                          
                            3.3
                          
                          
                            、虚拟多重继承,带虚函数,自己有新增虚函数(三个都是虚继承)

                          
                          
                            36
                          
                          
                            1
                          
                          >
                          
                            class
                          
                           Derived    size(
                          
                            36
                          
                          ):    
                          
                            //
                          
                          
                            多一张虚表
                          
                          
                            1
                          
                          >    +---

                          
                            1
                          
                          > 
                          
                            0
                          
                              | {vfptr}                         
                          
                            //
                          
                          
                            以空间换时间   新增虚函数,多张虚表
                          
                          
                            1
                          
                          > 
                          
                            4
                          
                              |
                          
                             {
                             vbptr 
                            }

                          
                          
                            1
                          
                          > 
                          
                            8
                          
                              |
                          
                             _iDerived

                          
                          
                            1
                          
                          >    +---

                          
                            1
                          
                          >    +--- (
                          
                            virtual
                          
                          
                            base
                          
                          
                             Base1)

                          
                          
                            1
                          
                          >
                          
                            12
                          
                              |
                          
                             {vfptr}

                          
                          
                            1
                          
                          >
                          
                            16
                          
                              |
                          
                             _iBase1

                          
                          
                            1
                          
                          >    +---

                          
                            1
                          
                          >    +--- (
                          
                            virtual
                          
                          
                            base
                          
                          
                             Base2)

                          
                          
                            1
                          
                          >
                          
                            20
                          
                              |
                          
                             {vfptr}

                          
                          
                            1
                          
                          >
                          
                            24
                          
                              |
                          
                             _iBase2

                          
                          
                            1
                          
                          >    +---

                          
                            1
                          
                          >    +--- (
                          
                            virtual
                          
                          
                            base
                          
                          
                             Base3)

                          
                          
                            1
                          
                          >
                          
                            28
                          
                              |
                          
                             {vfptr}

                          
                          
                            1
                          
                          >
                          
                            32
                          
                              |
                          
                             _iBase3

                          
                          
                            1
                          
                          >    +---

                          
                            1
                          
                          >
                          
                            Derived::$vftable@Derived@:

                          
                          
                            1
                          
                          >    | &
                          
                            Derived_meta

                          
                          
                            1
                          
                          >    |  
                          
                            0
                          
                          
                            1
                          
                          > 
                          
                            0
                          
                              | &
                          
                            Derived::g1

                          
                          
                            1
                          
                          >
                          
                            Derived::$
                             vbtable 
                            @:

                          
                          
                            1
                          
                          > 
                          
                            0
                          
                              | -
                          
                            4
                          
                          
                            1
                          
                          > 
                          
                            1
                          
                              | 
                          
                            8
                          
                           (Derivedd(Derived+
                          
                            4
                          
                          
                            )Base1)  //vbptr偏移8B找到虚基类Base1

                          
                          
                            1
                          
                          > 
                          
                            2
                          
                              | 
                          
                            16
                          
                           (Derivedd(Derived+
                          
                            4
                          
                          
                            )Base2)  // vbptr偏移16B找到虚基类Base2

                          
                          
                            1
                          
                          > 
                          
                            3
                          
                              | 
                          
                            24
                          
                           (Derivedd(Derived+
                          
                            4
                          
                          
                            )Base3)

                          
                          
                            1
                          
                          >
                          
                            Derived::$vftable@Base1@:

                          
                          
                            1
                          
                          >    | -
                          
                            12
                          
                          
                            1
                          
                          > 
                          
                            0
                          
                              | &
                          
                            Derived::f

                          
                          
                            1
                          
                          > 
                          
                            1
                          
                              | &
                          
                            Base1::g

                          
                          
                            1
                          
                          > 
                          
                            2
                          
                              | &
                          
                            Base1::h

                          
                          
                            1
                          
                          >
                          
                            Derived::$vftable@Base2@:

                          
                          
                            1
                          
                          >    | -
                          
                            20
                          
                          
                            1
                          
                          > 
                          
                            0
                          
                              | &thunk: 
                          
                            this
                          
                          -=
                          
                            8
                          
                          ; 
                          
                            goto
                          
                          
                             Derived::f

                          
                          
                            1
                          
                          > 
                          
                            1
                          
                              | &
                          
                            Base2::g

                          
                          
                            1
                          
                          > 
                          
                            2
                          
                              | &
                          
                            Base2::h

                          
                          
                            1
                          
                          >
                          
                            Derived::$vftable@Base3@:

                          
                          
                            1
                          
                          >    | -
                          
                            28
                          
                          
                            1
                          
                          > 
                          
                            0
                          
                              | &thunk: 
                          
                            this
                          
                          -=
                          
                            16
                          
                          ; 
                          
                            goto
                          
                          
                             Derived::f

                          
                          
                            1
                          
                          > 
                          
                            1
                          
                              | &
                          
                            Base3::g

                          
                          
                            1
                          
                          > 
                          
                            2
                          
                              | &Base3::h
                        

虚拟继承会将派生类的逻辑存到前面,3个Base都是虚继承,所以内存中的存放顺序为Derived、Base1、 Base2、Base3 。

在上一个例子的基础上,多一张虚表,所以占36B 。

  。

  。

 测试4、菱形虚继承 。

                          
                            4.1
                          
                          
                            、菱形普通继承(存储二义性)

                          
                          
                            48  B1、B2继承B;D继承B1、B2
                          
                          
                            class
                          
                           D    size(
                          
                            48
                          
                          
                            ):

                          
                          
                            1
                          
                          >    +---

                          
                            1
                          
                          > 
                          
                            0
                          
                              | +--- (
                          
                            base
                          
                          
                            class
                          
                          
                             B1)

                          
                          
                            1
                          
                          > 
                          
                            0
                          
                              | | +--- (
                          
                            base
                          
                          
                            class
                          
                          
                             B)

                          
                          
                            1
                          
                          > 
                          
                            0
                          
                              | | |
                          
                             {
                             vfptr 
                            }

                          
                          
                            1
                          
                          > 
                          
                            4
                          
                              | | | _ib             
                          
                            //
                          
                          
                            存储二义性
                          
                          
                            1
                          
                          > 
                          
                            8
                          
                              | | | _cb  
                          
                            //
                          
                          
                            1
                          
                          
                            1
                          
                          >      | | | <alignment member> (size=
                          
                            3
                          
                          ) 
                          
                            //
                          
                          
                            内存对齐
                          
                          
                            1
                          
                          >    | | +---

                          
                            1
                          
                          >
                          
                            12
                          
                              | |
                          
                             _ib1

                          
                          
                            1
                          
                          >
                          
                            16
                          
                              | |
                          
                             _cb1

                          
                          
                            1
                          
                          >      | | <alignment member> (size=
                          
                            3
                          
                          
                            )

                          
                          
                            1
                          
                          >    | +---

                          
                            1
                          
                          >
                          
                            20
                          
                              | +--- (
                          
                            base
                          
                          
                            class
                          
                          
                             B2)

                          
                          
                            1
                          
                          >
                          
                            20
                          
                              | | +--- (
                          
                            base
                          
                          
                            class
                          
                          
                             B)

                          
                          
                            1
                          
                          >
                          
                            20
                          
                              | | |
                          
                             {vfptr}

                          
                          
                            1
                          
                          >
                          
                            24
                          
                              | | | _ib           
                          
                            //
                          
                          
                            存储二义性
                          
                          
                            1
                          
                          >
                          
                            28
                          
                              | | |
                          
                             _cb

                          
                          
                            1
                          
                          >      | | | <alignment member> (size=
                          
                            3
                          
                          
                            )

                          
                          
                            1
                          
                          >    | | +---

                          
                            1
                          
                          >
                          
                            32
                          
                              | |
                          
                             _ib2

                          
                          
                            1
                          
                          >
                          
                            36
                          
                              | |
                          
                             _cb2

                          
                          
                            1
                          
                          >      | | <alignment member> (size=
                          
                            3
                          
                          
                            )

                          
                          
                            1
                          
                          >    | +---

                          
                            1
                          
                          >
                          
                            40
                          
                              |
                          
                             _id

                          
                          
                            1
                          
                          >
                          
                            44
                          
                              |
                          
                             _cd

                          
                          
                            1
                          
                          >      | <alignment member> (size=
                          
                            3
                          
                          
                            )

                          
                          
                            1
                          
                          >    +---

                          
                            1
                          
                          >
                          
                            D::$vftable@B1@:

                          
                          
                            1
                          
                          >    | &
                          
                            D_meta

                          
                          
                            1
                          
                          >    |  
                          
                            0
                          
                          
                            1
                          
                          > 
                          
                            0
                          
                              | &
                          
                            D::f

                          
                          
                            1
                          
                          > 
                          
                            1
                          
                              | &
                          
                            B::Bf

                          
                          
                            1
                          
                          > 
                          
                            2
                          
                              | &
                          
                            D::f1

                          
                          
                            1
                          
                          > 
                          
                            3
                          
                              | &
                          
                            B1::Bf1

                          
                          
                            1
                          
                          > 
                          
                            4
                          
                              | &
                          
                            D::Df

                          
                          
                            1
                          
                          >
                          
                            D::$vftable@B2@:

                          
                          
                            1
                          
                          >    | -
                          
                            20
                          
                          
                            1
                          
                          > 
                          
                            0
                          
                              | &thunk: 
                          
                            this
                          
                          -=
                          
                            20
                          
                          ; 
                          
                            goto
                          
                          
                             D::f

                          
                          
                            1
                          
                          > 
                          
                            1
                          
                              | &
                          
                            B::Bf

                          
                          
                            1
                          
                          > 
                          
                            2
                          
                              | &
                          
                            D::f2

                          
                          
                            1
                          
                          > 
                          
                            3
                          
                              | &B2::Bf2
                        

B的数据成员有两份,造成了存储二义性,共占48B 。

                          
                            4.2
                          
                          
                            、菱形虚拟继承        B1、B2虚拟继承B;D普通继承B1、B2

                          
                          
                            52
                          
                          
                            1
                          
                          >
                          
                            class
                          
                           D    size(
                          
                            52
                          
                          
                            ):

                          
                          
                            1
                          
                          >    +---

                          
                            1
                          
                          > 
                          
                            0
                          
                              | +--- (
                          
                            base
                          
                          
                            class
                          
                           B1)        
                          
                            //
                          
                          
                            基类B1
                          
                          
                            1
                          
                          > 
                          
                            0
                          
                              | |
                          
                             {vfptr}

                          
                          
                            1
                          
                          > 
                          
                            4
                          
                              | |
                          
                             {
                             vbptr 
                            }        // +36 找到虚基类

                          
                          
                            1
                          
                          > 
                          
                            8
                          
                              | |
                          
                             _ib1

                          
                          
                            1
                          
                          >
                          
                            12
                          
                              | |
                          
                             _cb1

                          
                          
                            1
                          
                          >      | | <alignment member> (size=
                          
                            3
                          
                          
                            )

                          
                          
                            1
                          
                          >    | +---               

                          
                            1
                          
                          >
                          
                            16
                          
                              | +--- (
                          
                            base
                          
                          
                            class
                          
                           B2)      
                          
                            //
                          
                          
                            基类B2
                          
                          
                            1
                          
                          >
                          
                            16
                          
                              | |
                          
                             {vfptr}

                          
                          
                            1
                          
                          >
                          
                            20
                          
                              | | {
                          
                            vbptr
                          
                          }      // +20找到虚基类

                          
                            1
                          
                          >
                          
                            24
                          
                              | |
                          
                             _ib2

                          
                          
                            1
                          
                          >
                          
                            28
                          
                              | |
                          
                             _cb2

                          
                          
                            1
                          
                          >      | | <alignment member> (size=
                          
                            3
                          
                          
                            )

                          
                          
                            1
                          
                          >    | +---

                          
                            1
                          
                          >
                          
                            32
                          
                              | _id          
                          
                            //
                          
                          
                            派生类D
                          
                          
                            1
                          
                          >
                          
                            36
                          
                              |
                          
                             _cd

                          
                          
                            1
                          
                          >      | <alignment member> (size=
                          
                            3
                          
                          
                            )

                          
                          
                            1
                          
                          >    +---

                          
                            1
                          
                          >    +--- (
                          
                            virtual
                          
                          
                            base
                          
                           B)   
                          
                            //
                          
                          
                            基类B
                          
                          
                            1
                          
                          >
                          
                            40
                          
                              |
                          
                             {vfptr}

                          
                          
                            1
                          
                          >
                          
                            44
                          
                              |
                          
                             _ib

                          
                          
                            1
                          
                          >
                          
                            48
                          
                              |
                          
                             _cb

                          
                          
                            1
                          
                          >      | <alignment member> (size=
                          
                            3
                          
                          
                            )

                          
                          
                            1
                          
                          >    +---

                          
                            1
                          
                          >
                          
                            D::$
                             vftable@B1@ 
                            :

                          
                          
                            1
                          
                          >    | &
                          
                            D_meta

                          
                          
                            1
                          
                          >    |  
                          
                            0
                          
                          
                            1
                          
                          > 
                          
                            0
                          
                              | &
                          
                            D::f1    // D中覆盖了

                          
                          
                            1
                          
                          > 
                          
                            1
                          
                              | &
                          
                            B1::Bf1 //新增

                          
                          
                            1
                          
                          > 
                          
                            2
                          
                              | &
                          
                            D::Df   //D中新增,放到B1的虚函数表中

                          
                          
                            1
                          
                          >
                          
                            D::$vftable@B2@:

                          
                          
                            1
                          
                          >    | -
                          
                            16
                          
                          
                            1
                          
                          > 
                          
                            0
                          
                              | &
                          
                            D::f2     // D中覆盖了

                          
                          
                            1
                          
                          > 
                          
                            1
                          
                              | &
                          
                            B2::Bf2  //新增

                          
                          
                            1
                          
                          >
                          
                            D::$
                             vbtable 
                            @B1@:

                          
                          
                            1
                          
                          > 
                          
                            0
                          
                              | -
                          
                            4        //距离派生类对象B1首地址偏移  -4
                          
                          
                            1
                          
                          > 
                          
                            1
                          
                              | 
                          
                            36
                          
                           (Dd(B1+
                          
                            4
                          
                          
                            )B)

                          
                          
                            1
                          
                          >
                          
                            D::$
                             vbtable 
                            @B2@:

                          
                          
                            1
                          
                          > 
                          
                            0
                          
                              | -
                          
                            4        //距离派生类对象B2首地址偏移  -4
                          
                          
                            1
                          
                          > 
                          
                            1
                          
                              | 
                          
                            20
                          
                           (Dd(B2+
                          
                            4
                          
                          
                            )B)

                          
                          
                            1
                          
                          >
                          
                            D::$vftable@B@:

                          
                          
                            1
                          
                          >    | -
                          
                            40
                          
                          
                            1
                          
                          > 
                          
                            0
                          
                              | &
                          
                            D::f

                          
                          
                            1
                          
                          > 
                          
                            1
                          
                              | &B::Bf
                        

B1、B2各有虚基指针 。

存储顺序本来是:派生类B1、基类B、派生类B2、基类B、派生类D 。

存储顺序:派生类B1、派生类B2、派生类D、基类B(基类放到后面,解决了存储二义性) 。

  。

最后此篇关于C++Day12虚拟继承内存布局测试的文章就讲到这里了,如果你想了解更多关于C++Day12虚拟继承内存布局测试的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com