对象模型的问题疑惑? sizeof的问题?

chp845 2014-02-21 02:59:42
#include <iostream>
#include <stdio.h>

using namespace std;

class X{};
class Y: public virtual X{};
class Z: public virtual X{};
class A: public Y, public Z{};

int main()
{
printf("Y:%d Z:%d A:%d\n", sizeof(Y), sizeof(Z), sizeof(A));
return 0;
}

运行平台:linux gcc4.6
结果:Y:8 Z:8 A:16

请问A为什么不是12?
按照对象模型中理论,A继承于X,X不论被继承多少层,都只有一个suboject 实体,不应该A大小为9吗,然后内存对其,最终sizeof为12吗?哪位解释下,为什么结果是16?
...全文
143 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
taodm 2014-02-21
  • 打赏
  • 举报
回复
哎,楼主《深度探索C++对象模型》基本白看了,竟然把virtual继承无视了。
unituniverse2 2014-02-21
  • 打赏
  • 举报
回复
补充一下,虚继承、虚函数的实现方式目前有虚表、二叉树、hash表等方式,现在主流的编译器多使用虚表这种实现方式、讨论的也比较多,但不要认为是标准规定了用虚表实现。虚表不是标准里的内容、标准也没规定该用什么方式实现虚函数、虚继承这些。
unituniverse2 2014-02-21
  • 打赏
  • 举报
回复
引用 6 楼 chp845 的回复:
[quote=引用 1 楼 lyyslsw 的回复:] [quote=引用 楼主 chp845 的回复:]
#include <iostream>
#include <stdio.h>

using namespace std;

class X{};
class Y: public virtual X{};
class Z: public virtual X{};
class A: public Y, public Z{};

int main()
{
    printf("Y:%d Z:%d A:%d\n", sizeof(Y), sizeof(Z), sizeof(A));
    return 0;
}
运行平台:linux gcc4.6 结果:Y:8 Z:8 A:16 请问A为什么不是12? 按照对象模型中理论,A继承于X,X不论被继承多少层,都只有一个suboject 实体,不应该A大小为9吗,然后内存对其,最终sizeof为12吗?哪位解释下,为什么结果是16?
这不是C++标准的东西吧, 这依赖于编译器自身[/quote] 标准上应该12,但是g++显示的好像不是12,而是16,所以,不明白g++对象模型是怎么样的呀?所以想请教下的呀![/quote] 标准从来没规定应该是多少。 你说的“g++对象模型”根本不是标准的内容,标准本身不是哪个具体的编译器厂商定的。 标准里有个关于大小的规定倒是,就是sizeof(X)不能为零,但是被另一个STD-LY类型(之前叫POD类型)继承S的时候,sizeof(S)可以只考虑S自身的成员占用情况(而让X在其中不占任何实际空间) 但是lz的例子里,Y、Z虚继承于X,结果Y、Z、A都已经不是STD-LY类型了,所以sizeof具体应该为多少,标准已经没有相应的规定了,只要是固定大小就行,编译器设计者可以自己决定
mujiok2003 2014-02-21
  • 打赏
  • 举报
回复
引用 9 楼 mujiok2003 的回复:
参考一下

c:\demo>type demo.cpp
#include <stdio.h>

using namespace std;

class X{};
class Y: public virtual X{};
class Z: public virtual X{};
class FooBar: public Y, public Z{};

int main()
{
      printf("Y:%d Z:%d A:%d\n", sizeof(Y), sizeof(Z), sizeof(FooBar));
      return 0;
}


c:\demo>cl /nologo /W4 /EHsc /d1reportSingleClassLayoutFooBar demo.cpp
demo.cpp
class FooBar    size(8):
        +---
        | +--- (base class Y)
 0      | | {vbptr}
        | +---
        | +--- (base class Z)
 4      | | {vbptr}
        | +---
        +---
        +--- (virtual base X)
        +---

FooBar::$vbtable@Y@:
 0      | 0
 1      | 8 (FooBard(Y+0)X)

FooBar::$vbtable@Z@:
 0      | 0
 1      | 4 (FooBard(Z+0)X)


vbi:       class  offset o.vbptr  o.vbte fVtorDisp
               X       8       0       4 0



c:\demo>demo
Y:4 Z:4 A:8

c:\demo>
vc 2010
mujiok2003 2014-02-21
  • 打赏
  • 举报
回复
参考一下

c:\demo>type demo.cpp
#include <stdio.h>

using namespace std;

class X{};
class Y: public virtual X{};
class Z: public virtual X{};
class FooBar: public Y, public Z{};

int main()
{
      printf("Y:%d Z:%d A:%d\n", sizeof(Y), sizeof(Z), sizeof(FooBar));
      return 0;
}


c:\demo>cl /nologo /W4 /EHsc /d1reportSingleClassLayoutFooBar demo.cpp
demo.cpp
class FooBar    size(8):
        +---
        | +--- (base class Y)
 0      | | {vbptr}
        | +---
        | +--- (base class Z)
 4      | | {vbptr}
        | +---
        +---
        +--- (virtual base X)
        +---

FooBar::$vbtable@Y@:
 0      | 0
 1      | 8 (FooBard(Y+0)X)

FooBar::$vbtable@Z@:
 0      | 0
 1      | 4 (FooBard(Z+0)X)


vbi:       class  offset o.vbptr  o.vbte fVtorDisp
               X       8       0       4 0



c:\demo>demo
Y:4 Z:4 A:8

c:\demo>
Pump天天学习 2014-02-21
  • 打赏
  • 举报
回复
lz这个明显是inside the c++ object model上面的例子, 书上说的很明确了 视编译器而定
AndyStevens 2014-02-21
  • 打赏
  • 举报
回复
研究包含虚基类的对象的大小 没有太大意义,因为不同编译器的实现差异太大。
chp845 2014-02-21
  • 打赏
  • 举报
回复
引用 1 楼 lyyslsw 的回复:
[quote=引用 楼主 chp845 的回复:]
#include <iostream>
#include <stdio.h>

using namespace std;

class X{};
class Y: public virtual X{};
class Z: public virtual X{};
class A: public Y, public Z{};

int main()
{
    printf("Y:%d Z:%d A:%d\n", sizeof(Y), sizeof(Z), sizeof(A));
    return 0;
}
运行平台:linux gcc4.6 结果:Y:8 Z:8 A:16 请问A为什么不是12? 按照对象模型中理论,A继承于X,X不论被继承多少层,都只有一个suboject 实体,不应该A大小为9吗,然后内存对其,最终sizeof为12吗?哪位解释下,为什么结果是16?
这不是C++标准的东西吧, 这依赖于编译器自身[/quote] 标准上应该12,但是g++显示的好像不是12,而是16,所以,不明白g++对象模型是怎么样的呀?所以想请教下的呀!
chp845 2014-02-21
  • 打赏
  • 举报
回复
引用 2 楼 derekrose 的回复:
楼主知道不知道有个东西叫virtual table
不知道的话,我能够知道标准上:应该是9吗?
derekrose 2014-02-21
  • 打赏
  • 举报
回复
引用 2 楼 derekrose 的回复:
楼主知道不知道有个东西叫virtual table
诶 是空的class啊 楼主可以debug看一看A里面到底有什么 我也忘了。。。
幻夢之葉 2014-02-21
  • 打赏
  • 举报
回复
恩,这要看自身编译器的实现!!好像论坛蛮多这样子的讨论贴
derekrose 2014-02-21
  • 打赏
  • 举报
回复
楼主知道不知道有个东西叫virtual table
Johnblx 2014-02-21
  • 打赏
  • 举报
回复
引用 楼主 chp845 的回复:
#include <iostream>
#include <stdio.h>

using namespace std;

class X{};
class Y: public virtual X{};
class Z: public virtual X{};
class A: public Y, public Z{};

int main()
{
    printf("Y:%d Z:%d A:%d\n", sizeof(Y), sizeof(Z), sizeof(A));
    return 0;
}
运行平台:linux gcc4.6 结果:Y:8 Z:8 A:16 请问A为什么不是12? 按照对象模型中理论,A继承于X,X不论被继承多少层,都只有一个suboject 实体,不应该A大小为9吗,然后内存对其,最终sizeof为12吗?哪位解释下,为什么结果是16?
这不是C++标准的东西吧, 这依赖于编译器自身

64,639

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧