返回信息流#include <iostream>
using namespace std;
class A
{
public: //此处有无影响B的大小
int n;
char a;
};
class B : public A
{
char b;
};
int main()
{
cout<<sizeof(A)<<endl; //8
cout<<sizeof(B)<<endl; //12,但是当A的数据成员变为private之后(即注释掉public关键字之后), sizeof(B)=8
system("pause");
return 0;
}
为什么会这样呢?
环境: dev c++
这是一条镜像帖。来源:北邮人论坛 / cpp / #31447同步于 2009/11/16
该镜像源已超过 30 天没有更新,可能在源站已被删除。
CPP机器人发帖
为什么sizeof的值会不同呢?
AAJ
2009/11/16镜像同步8 回复
订阅后,新回复会通过你的通知中心匿名送达。
8 条回复
B中有一个vptr
public时的B:4(int) + 1(char) + 1(char) + 2(padding) + 4(vptr)=12
private时的B:1(char) + 3(padding) + 4(vptr)=8
【 在 AAJ 的大作中提到: 】
: #include <iostream>
: using namespace std;
: class A
: ...................
【 在 allen0308 的大作中提到: 】
: B中有一个vptr
: public时的B:4(int) + 1(char) + 1(char) + 2(padding) + 4(vptr)=12
: private时的B:1(char) + 3(padding) + 4(vptr)=8
不对,如果A中只有一个char时,B大小是2,不是8
【 在 AAJ 的大作中提到: 】
: #include <iostream>
: using namespace std;
: class A
: ...................
无语了,又讨论这种问题了……
不小心 一辈子被 编译器 牵着走……
很明显,这个是 对齐产生的结果。怎么对齐,不同的编译器有不同的要求。哪天你自己牛逼了,你也写个编译器,然后结果就一直保持12,而不是8.
这里没什么虚函数表指针,这边没有虚函数,何来虚函数指针。
根本原因,对齐
回得太快且欠考虑了...
修改一下吧。
没有声明virtual function所以没有vptr
当继承without多态时,B中自己的数据是在基类A的数据padding之后存储的,并且理论上讲public和private对sizeof并没有影响,所以大小为
4+1+3(padding)+1+3(padding)=12
我想你改为private之后sizeof为8是因为编译器做了优化,我的code::blocks也为8,但vc为12
【 在 ding328 的大作中提到: 】
: 不对,如果A中只有一个char时,B大小是2,不是8
【 在 AAJ 的大作中提到: 】
: #include <iostream>
: using namespace std;
: class A
: ...................
这个应该是和编译器有关的。我的VS2008上是不变的。Code::Blocks 和你结果一样,具体试了很长时间,我是这么理解的:(虽然很牵强,但这么想可以理解问题)
当基类有private成员的时候,派生类的成员变量对齐时不考虑基类最后的补齐。当基类只有public成员的时候,派生类对齐时,在基类总大小的基础上再分派存储空间。
则修改之前的对齐方式为:(4+1+补齐3位)+1+补齐3位=12
修改后的对齐方式为:4+1+1+补齐2位=8
只有这样解释了
单就这一点来看还是g++强大
【 在 ding328 的大作中提到: 】
: 这个应该是和编译器有关的。我的VS2008上是不变的。Code::Blocks 和你结果一样,具体试了很长时间,我是这么理解的:(虽然很牵强,但这么想可以理解问题)
: 当基类有private成员的时候,派生类的成员变量对齐时不考虑基类最后的补齐。当基类只有public成员的时候,派生类对齐时,在基类总大小的基础上再分派存储空间。
: 则修改之前的对齐方式为:(4+1+补齐3位)+1+补齐3位=12
: ...................
编译器
【 在 AAJ (大卫) 的大作中提到: 】
: #include <iostream>
: using namespace std;
: class A
: ...................