C++继承时的对象内存模型

最近在复习c++ 继承多态的相关知识,看的头大,来做个总结,giao~

单继承时的内存模型

class base1
{
public:
    virtual void g1(){}
    virtual void f1(){}
    virtual void h1(){}
public:
    int ba1 = 10;
};

class child:public base1 {
public:
    void g1(){} //重写g1函数
    void f2(){}
private:
    int chi = 20;
};
 sizeof(child) = sizeof(ba1)+sizeof(chi)+sizeof(vfptr) = 12 .
1>class child	size(12):
1>	+---
1> 0	| +--- (base class base1)
1> 0	| | {vfptr}              //虚函数指针
1> 4	| | ba1                  //基类变量
1>	| +---
1> 8	| chi                    //子类成员
1>	+---
1>
1>child::$vftable@:              //vfptr指向这里vftable
1>	| &child_meta
1>	|  0
1> 0	| &child::g1             //地址替换为子类的地址
1> 1	| &base1::f1
1> 2	| &base1::h1
1>

多继承时的内存布局

class base1
{
public:
    virtual void g1(){}
    virtual void f1(){}
    virtual void h1(){}
public:
    int ba1 = 10;
};
class base2
{
public:
    virtual void g2() {}
    virtual void f2() {}
    virtual void h2() {}
public:
    int ba2 = 20;
};
class child:public base1,public base2 {    //同时继承两个类base1 和base2
public:
    void g1(){}                            //重写base1 的g1    
    void f2(){}                            //重写base2 的f2
private:
    int chi = 20;
};
sizeof(child) = sizeof(ba1)+sizeof(vfptr1)+sizeof(ba2)+sizeof(vfptr2)+sizeof(chi) = 20.
1>class child	size(20):
1>	+---
1> 0	| +--- (base class base1)
1> 0	| | {vfptr}            //vfptr1
1> 4	| | ba1
1>	| +---
1> 8	| +--- (base class base2)
1> 8	| | {vfptr}            //vfptr2
1>12	| | ba2
1>	| +---
1>16	| chi
1>	+---
1>
1>child::$vftable@base1@:
1>	| &child_meta
1>	|  0
1> 0	| &child::g1            //替换重写后方法地址
1> 1	| &base1::f1
1> 2	| &base1::h1
1>
1>child::$vftable@base2@:
1>	| -8
1> 0	| &base2::g2
1> 1	| &child::f2            //替换重写后方法地址
1> 2	| &base2::h2

菱形继承,虚继承的内存布局:

class base {
public:
    virtual void m(){}
public:
    int x = 0;
};
class base1:virtual public base    //虚继承
{
public:
    virtual void g1(){}
    virtual void f1(){}
    virtual void h1(){}
public:
    int ba1 = 10;
};
class base2 :virtual public base    /虚继承
{
public:
    virtual void g2() {}
    virtual void f2() {}
    virtual void h2() {}
public:
    int ba2 = 20;
};
class child:public base1,public base2 {
public:
    void g1() {}
    void f2(){}
private:
    int chi = 20;
};

sizeof(child) = 36

1>class child	size(36):
1>	+---
1> 0	| +--- (base class base1)
1> 0	| | {vfptr}
1> 4	| | {vbptr}
1> 8	| | ba1
1>	| +---
1>12	| +--- (base class base2)
1>12	| | {vfptr}
1>16	| | {vbptr}
1>20	| | ba2
1>	| +---
1>24	| chi
1>	+---
1>	+--- (virtual base base)    //base 只存在一份,base1 和base2 的vfptr指向这里
1>28	| {vfptr}
1>32	| x                     // 操作x不会造成二义性
1>	+---
1>
1>child::$vftable@base1@:
1>	| &child_meta
1>	|  0
1> 0	| &child::g1
1> 1	| &base1::f1
1> 2	| &base1::h1
1>
1>child::$vftable@base2@:
1>	| -12
1> 0	| &base2::g2
1> 1	| &child::f2
1> 2	| &base2::h2


版权声明:本文为qq_40340448原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。