c++ 类对象内存分布模型(基于vs2017 32位)

本文详细解析了C++中虚函数与各种继承方式(包括单一、多重、虚拟继承等)下的内存布局规律,揭示了虚函数表指针的位置及其对类成员分布的影响。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

class A0{};

1.没有继承,不含有虚函数的类

class A1
{
private:
    int a;
    int b;
};

2.没有继承,含有虚函数的类

class A2
{
private:
    int a;
    int b;
public:
    virtual void f1()
    {

    }
};

3.单一继承,父类不含有虚函数,该类不含虚函数

class A3 :public A1
{
public:
    int c;
};

4.单一继承,父类含有虚函数,该类不含虚函数

class A4 :public A2
{
public:
    int d;
    //void f1(){}//如果f1重载的话,请观察两者的不同
    
};

5.单一继承,父类不含有虚函数,该类含虚函数

class A5:public A1
{
public:
    int e;
    virtual void f2(){}

};

6.单一继承,父类含有虚函数,该类含虚函数

class A6 :public A2
{
public:
    int e;
    virtual void f2() {}

};

7.多重继承,父类1不含虚函数,父类11不含虚函数,该类不含虚函数

class A11
{
public:
    int a1;
    int b1;
};
class A7 :public A1, public A11
{
public:
    int a7;
};

8.多重继承,父类1不含虚函数,父类11不含虚函数,该类含虚函数

class A8 :public A1, public A11
{
public:
    int a7;
    virtual void f8(){}
};

9.多重继承,父类1不含虚函数,父类2含虚函数,该类不含虚函数

class A9 :public A1, public A2
{
public:
    int a9;
};

10.多重继承,父类1不含虚函数,父类2含虚函数,该类含虚函数

class A10 :public A1, public A2
{
public:
    int a10;
    virtual void f10(){}
};

11.多重继承,父类2含虚函数,父类1不含虚函数,该类不含虚函数

class AA1 :public A2, public A1
{
public:
    int aa1;
   
};

12.多重继承,父类2含虚函数,父类1不含虚函数,该类含虚函数

class AA2 :public A2, public A1
{
public:
    int aa2;
    virtual void f10() {}
};

13.多重继承,父类1含虚函数,父类2含虚函数,该类不含虚函数

class A22
{
private:
    int a;
    int b;
public:
    virtual void f1()
    {

    }
};
class AA3 :public A2, public A22
{
public:
    int aa3;
};

14.多重继承,父类1含虚函数,父类2含虚函数,该类含虚函数

class AA4 :public A2, public A22
{
public:
    int aa4;
    virtual void f4(){}
};

15.单一虚拟继承,父类不含虚函数,该类不含虚函数

class AA5 :virtual public A1
{
public:
    int aa5;
    
};

16.单一虚拟继承,父类不含虚函数,该类含虚函数

class AA6 :virtual public A1
{
public:
    int aa5;
    virtual void f4() {}
};

17.单一虚拟继承,父类含虚函数,该类不含虚函数

class AA7 :virtual public A2
{
public:
    int aa2;
};

16.单一虚拟继承,父类含虚函数,该类含虚函数

class AA8 :virtual public A2
{
public:
    int aa2;
    virtual void f8(){}
};

17.多重虚拟继承,父类1和11均不含虚函数,该类不含虚函数

class AB1 :virtual public A1, virtual public A11
{
public:
    int ab1;
};

18.多重虚拟继承,父类1.2均含虚函数,该类不含虚函数

class AB2 :virtual public A2, virtual public A22
{
public:
    int ab2;
};

19.多重虚拟继承,父类其中一个含虚函数,另一个不含虚函数,该类不含虚函数

class AB3 :virtual public A2, virtual public A1
{
public:
    int ab3;
};

17.多重虚拟继承,父类1.2均不含虚函数,该类含虚函数

class AB4 :virtual public A1, virtual public A11
{
public:
    int ab1;
    virtual void f4(){}
};

18.多重虚拟继承,父类1.2均含虚函数,该类含虚函数

class AB5 :virtual public A2, virtual public A22
{
public:
    int ab2;
    virtual void f5(){}
};

19.多重虚拟继承,父类其中一个含虚函数,另一个不含虚函数,该类含虚函数

class AB6 :virtual public A2, virtual public A1
{
public:
    int ab3;
    virtual void f6() {}
};

class AB6 :virtual public A2, virtual public A1
{
public:
    int ab3;
    virtual void f6() {}
};

A.不含有虚基类的多重继承

class B3 : public A2
{
public:
    int b3;
    virtual void fb1() {}
};

class B4 : public A2
{
public:
    int b4;
    virtual void fb2() {}
};

class C2 : public B3, public B4
{
public:
    int c2;
    virtual void fc2() {}
};

B.含有虚基类的多重继承

class B1 :virtual public A2
{
public:
    int b1;
    virtual void fb1(){}
};

class B2 :virtual public A2
{
public:
    int b2;
    virtual void fb2() {}
};

class C1 :public B1, public B2
{
public:
    int c1;
    virtual void fc1() {}
};

 

总结:

1.无继承时候,有虚函数的话,指向虚函数表的指针总是位于第一位,其他的数据按声明的顺序进行内存分布;

2.单一的非虚拟继承时候,当父类或者子类其中之一或者两者都有虚函数的时候,指向虚函数表的指针总是在第一位,然后是父类成员,再然后是该类成员;

3.单一的虚拟继承时候,显示该类的分布,然后才是父类的分布,如果该类有虚函数,那么第一位就是指向该虚函数表的指针,然后就是指向虚基类的指针,再然后是该类的成员,在后面就是虚基类的分布了;

4.多重的非虚拟继承时候,首先分布的是含有虚函数的基类,第一是该指向该基类虚函数表的指针,然后是该基类其他成员,然后是第二个基类的分布,与第一个相同;

5.多重的虚拟继承时候,先是该类成员分布,其中有虚函数的话,第一个就是指向该虚函数表的指针,然后是虚基类表的指针,然后是本类其他数据成员,后面就是虚基类在内存中的分布了;

6.虚基类是如何消除子类对象中数据重复性,可见A B;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值