学会从C++ Object Model中着手分析
1. 需要多少内存才能表现一个class object? 一般而言要有:
· 其nonstatic data members的总和大小;
· 加上任何由于alignment的需求而填补(padding)上去的空间 (可能存在于members之间,也可能存在于集合体边界);
· 加上为了支持virtual而由内部产生的任何额外负担。
2. Nontrivial default constructor产生的条件
(如果class没有明确定义default constructor, 编译器需要为某class合成出nontrivial default constructor. 同时编译器会扩张已存在的constructors, 在其中安插一些必须初始化代码。那么什么时候会需要必需的初始化代码呢?):
· 包含有“拥有Default Constructor”的Member Class Object(必需的初始化代码是调用这些Member Class Object的Default Constructor)
· “带有Default Constructor”的Base Class (必需的初始化代码是调用上一层base classes的default constructor)
· “带有一个Virtual Function”的Class, 包括class声明(或继承)一个virtual function. (必需的初始化代码是virtual function table和vptr)
· “带有一个Virtual Base Class”的Class (必需的初始化是添加指向virtual base class的指针,以帮助代码执行其对虚基类成员访问时的必要跳转)
3. 正如trivial default constructor总是不用你操心,Bitwise Copy Semantics也总是缺生存在,不影响你copy construct和copy assignment operator.
同样的道理在以下情况(不符合Bitwise Copy Semantics),编译器会特别添加代码。
· 当class 内含一个member object而后者的class声明有一个copy constructor时;
· 当class继承自一个base class而后者存在有一个copy constructor时;
· 当class声明了一个或多个virtual functions时;
· 当class派生自一个继承串链,其中有一个或多个virtual base class时。
Note: Trivial or Nontrivial default constructor (copy constructor, copy assignment operator)都是针对于编译器而言。程序员请根据语义的需要决定是否需要自定义explicit constructor. 例如,当你需要设置data members的初始化值时,当你不希望经过拷贝构造后指针member指向同样的一块内存区域等等。
4. 编译器会对initialization list一一处理并可能重新排序,以反映出members的声明次序,它会安插代码到constructor体内,并置于任何explicit user code之前。