C/C++编程:空类不空
#include <iostream>
class X{
};
class Y : public virtual X{
};
class Z : public virtual X{
};
class A : public Y, public Z{
};
int main() {
printf("%d, %d, %d, %d", sizeof(X), sizeof(Y), sizeof(Z), sizeof(A));
}
分析:对于空类
// sizeof X === 1;
class X{
};
- 实际上它并不是空的,它有一个隐式的1byte,那是被编译器安插进入的一个
char
。 这使得这个类的两个object可以在内存中获得一个独一无二的地址:
X a, b;
if(&a == &b){printf("empty class is not empty");
}
对于:
// sizeof Y == sizeof Z == 8
class Y : public virtual X{
};
class Z : public virtual X{
};
Y和Z的大小在不同编译器不同机器上的结果是不一样的(目前是8).事实上,Y和Z的大小受到三个因素的影响:
- 语言本身所造成的额外负担:当语言支持虚基类时,就会导致一些额外负担。在派生类中,这个额外负担反映在某种形式的指针身上,它或者指向虚基类子对象(subobject),或者指向一个相关表格:表格中存在的是虚基类子对象的地址,或者偏移量
- 编译器对特殊情况所提供的优化处理:虚基类X子对象的1bytes大小也出现在类Y和Z身上。传统上它被放在派生类的固定(不变动)部分的尾端。某些编译器会对空虚基类提供特殊支持。(但是本机上没有这个支持)
- 对齐的限制:大部分机器上,群聚的结构体大小会受到对齐的限制,使得它们更有效率的存取
空基类提供了一个虚拟接口,没有定义任何数据。某些新近的编译器比如vs对此提供了特殊处理。在这个策略下,一个空虚基类被视为派生类对象最开头的一部分,也就是说它并没有花费任何的额外空间。这就节省了上面第2点的1bytes(因为已经有了成员就不需要为空类再安插一个char),也就是不需要第3点的3bytes对齐填补。在这个模型下,Y和Z的大小都是4而不是8
还没有评论,来说两句吧...