C++多继承中的内存布局(2)

接上文,还是先看一个例子:

struct base {
   int value = 99;
};
struct offset {
   char space[10] = "abc";
};
struct derived : offset, base {
   int dvalue = 0;
};

derived的内存布局应该是先存放offset的内容,再存放base的内容,最后存放derived自己的成员,按照4字节对齐,这个很容易验证:

如果我们添加虚函数:

struct base {
   int value = 99;
   virtual void foo() { std::cout << value << std::endl; }
   virtual void bar() { std::cout << value << std::endl; }
};
struct offset {
   char space[10] = "abc";
};
struct derived : offset, base {
   int dvalue = 0;
   virtual void foo() { std::cout << value << "," << dvalue << std::endl; }
};

这个时候便不再是先存放space的内容了,因为内存最开始的地方要存放vptr,且由于只有base有虚函数,因此可以共用这个vptr,所以在内存布局上会把base放到前面来,按8字节对齐:

且此时,在第二个block中,存放value后还剩四个字节,可以继续存放space的4个char,这个被称作"tail padding"。

验证一下:

typedef long long u64;
derived d;
base * b = &d; // This generates an offset
cout << sizeof(derived) << endl; //
cout << *((int*)((u64*)(b) + 1)) <<endl;
cout << *((int*)((u64*)(b) + 3)) <<endl;
cout << *((char*)((u64*)(b) + 1) + 4) <<endl;

按照上述分析,应该输出:32,99,0,a:

#面试##面经##笔经##C++##面试题刺客退退退#
全部评论

相关推荐

伟大的烤冷面被普调:暨大✌🏻就是强
点赞 评论 收藏
分享
3 1 评论
分享
牛客网
牛客企业服务