#include <stdio.h>
class X
{
};
class Y
{
// long x; // case A)
// X x; // case B)
};
class Z : public Y, public X
{
};
int main() {
Z z;
printf("%d %d %d\n",
sizeof(Z), sizeof(Y), (char*)static_cast<X*>(&z) - (char*)&z);
return 0;
}
在取消注释案例A或案例B之后,为什么输出如下:
答:4 4 4
B:2 1 2
为什么{B}表示sizeof(Y) != sizeof(Z)
,但A)情况相同。谁能解释一下?
答案 0 :(得分:4)
我的记忆对此很模糊,但我认为这是因为Z的两个X子对象(基类X和Y :: x)必须具有不同的地址。
答案 1 :(得分:1)
仍然要求空类的大小至少为1.但这并不意味着他们必须将这个大小赋予他们的子类。
答案 2 :(得分:1)
我在空基类问题上遇到了类似的问题并找到了解释。
ISO / IEC 14882:2003 10-5
基类子对象可以是零大小(第9条);然而,两个 具有相同类类型且属于同一类的子对象 大多数派生对象不得分配在同一地址(5.10)。
这意味着如果Y的对象有两个X子对象,则两个X必须具有不同的地址(它们必须是具有不同地址的2个不同对象)。
顺便说一下,空基类不必为0大小(它表示可能是),直到C ++ 11,它声称需要它,更多参考: http://en.cppreference.com/w/cpp/language/ebo
答案 3 :(得分:0)
只需添加一些代码:
#include <stdio.h>
class X
{
};
class Y
{
// long x; // case A)
public:
X x; // case B)
};
class Z : public Y, public X
{
};
int main() {
Z z;
printf("%d %d %d\n", sizeof(Z), sizeof(Y), (char*)static_cast<X*>(&z) - (char*)&z);
printf("%p %p %p %p\n", &z, static_cast<Y*>(&z), static_cast<X*>(&z), &z.x);
return 0;
}
在我的机器上,我得到了:
2 1 1
0x7fff8876fcb0 0x7fff8876fcb0 0x7fff8876fcb1 0x7fff8876fcb0
^^Z ^^Y ^^X Z::x
因此,X
个对象占用了两个字节。一个是基类,另一个是Y
中存在的基类。