C++:使用继承的类的内存布局

Rak*_*kib 3 c++ inheritance multiple-inheritance memory-layout

我知道标准没有规定如何打包数据.我只是试图了解类的内存布局(尤其是如何dynamic_cast<void*>保证返回指向最派生类的开头的指针).我想不出有关以下代码输出的任何解释:

struct A{ int a;};
struct B{ int b;};
struct C: public A, public B { int c;};
struct D:public C {int d;};


int main(){
  D* ob=new D;
  A* a = ob;
  B* b = ob;
  C* c = ob;
}
Run Code Online (Sandbox Code Playgroud)

打印指针的值表明,a,c,d有总是相同的值,只b添加4个字节偏移量.这是偶然的吗?或者背后有一个逻辑?

编辑: 从概念上讲,布局应该像图像一样,但不知何故,点A,C和D合并为一个.在此输入图像描述

ikh*_*ikh 7

首先,你struct A

| int a |
Run Code Online (Sandbox Code Playgroud)

并且B

| int b |
Run Code Online (Sandbox Code Playgroud)

struct C继承struct Astruct B,它也有一个成员,int c.所以它可以有这样的布局:

            struct B
struct A     /
   \        /
| int a | int b | int c |
Run Code Online (Sandbox Code Playgroud)

并且struct D,继承struct C,是

            struct B
struct A     /
   \        /
| int a | int b | int c | int d |
\-----------------------/
         struct C
Run Code Online (Sandbox Code Playgroud)

现在想一想D* ob = new D;.它会是这样的:

| int a | int b | int c | int d |
^
\
 ob
Run Code Online (Sandbox Code Playgroud)

并考虑A* a = ob- struct A是偏移0 struct D,所以它是

| int a | int b | int c | int d |
^
\
 a
Run Code Online (Sandbox Code Playgroud)

它等于struct c.

然而,当谈到struct B它时,它是在偏移量4(if sizeof(int) == 4)上,所以它是 -

| int a | int b | int c | int d |
        ^
        /
       b
Run Code Online (Sandbox Code Playgroud)

请注意,布局未在标准中定义,并且每个实现可能不同.我向您展示了一种可能的布局.

有关高级信息,建议您阅读"空类"的C++多重继承内存布局.

  • +1用于指出标准没有指定任何内容.值得注意的是,这是"逻辑"内存布局.实际上,根据操作系统的判断,内存可能会在更多而不是连续的页面中分散. (2认同)