class X{};
class Y:virtual public X{};
class Z:virtual public X{};
class B:virtual public X{};
class A:public Y,public Z,public B{};
class M{};
class N:virtual public X,virtual public M
{
};
int main()
{
cout<<sizeof(X)<<endl;
cout<<sizeof(Y)<<endl;
cout<<sizeof(Z)<<endl;
cout<<sizeof(A)<<endl;
cout<<endl<<endl<<sizeof(N)<<endl;
return 0;
}
Code::Block 1 4 4 12 4
VS2008 1 4 4 12 8
C++ Standard并不强制规定如“base class subobjects的排列次序”,或“不同存取层级的data member的排列次序”。
C++对象模型尽量以空间优化和存取速度优化的考虑来表现nonstaticdata members,并且保持和C语言struct数据配置的兼容性。它把数据直接存放在每一个class object之中。对于继承而来的nonstatic data members也是如此。不过并没有强制定义其间的排列次序。
每一个class object因此必须有足够的大小以容纳它所有的nonstatic data members。因为它可能比你想象的还大。
1,由编译器自动加上的额外data members,用以支持某些语言特性(主要是各种virtual 特性)。
2,因为alignment(边界调整)的需要。
对member functions本身的分析,会直到整个class的声明都出现了才开始。因此,在一个inline member function躯体之内的一个datamember绑定操作,会在整个class声明完成之后才发生。
然而,这对于member function的argument list并不为真。Argemment list中的名称还是会在它们第一次遭遇时被适当地决议完成。
typedef intlength;
class Point
{
public:
void fun(length a)
{
cout<<typeid(a).name()<<endl; //i
cout<<typeid(_a).name()<<endl; //f
}
typedef float length;
length _a;
};
DataMemberr的布局
C++ Standard 要求,在同一个access section中,members的排列只需符合“较晚出现的members在class object中有较高的地址”这一条件即可,也就是说,各个members并不一定得连续排列,相对次序不会改变,什么东西可能会介于被声明的members之间呢?members的边界调整(alignment)可能 就需要填补一些bytes。编译器还可能会合成一些内部使用的data members,以支持整个对象模型。
C++ Standard秉持先前所说的“对于内存所持的放任态度”。
C++ Standard也允许编译器将多个access section之中的data members自由排列,不必在乎它们出现在class声明中的次序。
每一个static data member只有一个实体,存放在程序的data segment之中。
若取一个static data member的地址,会得到一个指向其数据类型的指针。
如果有两个classes,每一个都声明了一个static member freelist,那么当它们都被放在程序的data segment时,就会导致名称冲突。编译器的解决方法是暗中对每一个static data member编码,名字重组(name-mangleing),以获得一个独一无二的程序识别代码。
Nonstatic datamembers直接存放在每一个classobject之中。除非经由明确的或暗喻的classobject,没有办法直接存取它们。
欲对一个nonstatic data member进行存取操作,编译器需要把class