C ++:使用继承的类的内存布局 [英] C++: Memory layout of classes using inheritance

查看:178
本文介绍了C ++:使用继承的类的内存布局的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道数据如何被打包没有被标准规定。我只是试图得到一个关于类的内存布局的想法(尤其是如何 dynamic_cast 保证返回一个指针到最大的派生类的开始)。我不能想到关于以下代码的输出的任何解释:

  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;
}

打印指针的值显示, a , c d 总是相同的值,只有 b 添加4字节作为偏移量。是偶然吗?



编辑:
从概念上讲,布局应该像图像,但不知何故,点A ,C和D合并为一个。

首先, struct A

  | int a | 

B

  | int b | 

struct C 继承 struct A struct B ,并且还有一个成员 int c 。所以它可以有这样的布局:

  struct B 
struct A /
\ /
| int a | int b | int c |

struct D c $ c> struct C

  struct B 
struct A /
\ /
| int a | int b | int c | int d |
\ ----------------------- /
struct C

现在考虑 D * ob = new D; 。它将是这样:

  | int a | int b | int c | int d | 
^
\
ob

c $ c> A * a = ob - 结构A 位于 struct D ,因此是

  | int a | int b | int c | int d | 
^
\
a

但是,当涉及到 struct B 时,会出现这样的情况:$ c> struct c 。



<它在偏移4(如果 sizeof(int)== 4 ),所以它是 -

 code> | int a | int b | int c | int d | 
^
/
b


请注意,布局没有在标准中定义,并且每个实现可以不同。我向你展示了一个可能的布局。



如需进阶资讯,建议您阅读 C ++具有空类的多重继承内存布局

I know how data will be packed is not specified by the standard. I was just trying to get an idea about the memory layout of classes ( esp. how dynamic_cast<void*> guarantees to return a pointer to the start of the most derived class). I could not think of any explanation about the output of the following code:

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;
}

Printing the values of the pointers shows that, a,c,d have always same value, only b is added 4 Bytes as offset. Is it accidental? Or there is a logic behind it?

Edit: Conceptually the layout should be like the image,but somehow the points A,C and D merges to one.

解决方案

First, your struct A is

| int a |

and B is

| int b |

struct C inherits struct A and struct B, and it also has one member, int c. So it can have a layout like this:

            struct B
struct A     /
   \        /
| int a | int b | int c |

and struct D, which inherits struct C, is

            struct B
struct A     /
   \        /
| int a | int b | int c | int d |
\-----------------------/
         struct C

Now think about D* ob = new D;. It'll be like this:

| int a | int b | int c | int d |
^
\
 ob

And think about A* a = ob - struct A is on offset 0 of struct D, So it is

| int a | int b | int c | int d |
^
\
 a

It's equal to struct c.

However, when it comes to struct B, it's on offset 4 (if sizeof(int) == 4), So it's -

| int a | int b | int c | int d |
        ^
        /
       b

Notice that the layout is not defined in standard, and it can be different each implementation. I showed you one of possible layouts.

For an advanced information, I suggest you to read C++ Multiple Inheritance Memory Layout with "Empty classes".

这篇关于C ++:使用继承的类的内存布局的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆