default constructor 会在需要的时候被编译器产生出来
----<<Inside C++ Object Model>>
一切从这开始, 是在谁需要的时候? 考察以下代码: class Foo{public: int val; Foo *pnext}; void FooBar() { //Foo Object 须在此初始化Foo bar;if(bar.val || bar.pnext)//do something... } 编译器不会为其产生一个 default constructor, 因为这是程序需要而不是编译器需要, 程序有需要, 那是程序员的责任, 因此上述代码不会合成一个 default constructor. 那么在那些情况下是编译器需要构建 default constructor 的情况呢? 1. 带有 Default Constructor 的 Member Class Object但出现一个问题, 怎样防止在不同模块中生成多个 default constructor?解决方法是, 把合成的 default constructor 都以 inline 的方式完成, inline 函数有静态连接, 不会被文件以外看到, 如果函数太复杂, 不适合做出一个 inline, 编译器则会做出一个 explicit non-inline static 实体. 考察以下代码:class Foo{public: Foo(){} Foo(int){/* do something */}...};class Bar{private: Foo foo; char *pstr;};void FooBar(){ //bar Object 需要在此初始化Bar barif(str)...}此例中, 编译器会产生 bar 的 default constructor 来调用 class Foo 的 default constructor 初始化 Bar::foo, bar 的 default constructor 中, 并不存在初始化 str 的代码, 因为那是程序员的责任.那么如果程序员已定义了用来初始化 str 的 constructor, 如:Bar::bar(){str = 0;}那么编译器会怎样做呢, 它会扩展你的代码, 在你的代码之前添加必要的 default constructor 即://你看上去的Bar::bar(){str = 0;}//实际可能是Bar::bar(){Foo::Foo(); str = 0;}问题又来了, 假如 class 中 有多个 member object 嗷嗷待哺呢?结果是, 编译器会按照其声明的顺序初始化. 2. 带有 Default Constructor 的 Base Class我倾向于用一个例子说明问题:class Member{public: Member(){std::cout << "member\n";}} class Base1 { public: Base1(){public: std::cout << "base1";}private: Member m;};public: Base2(){public: std::cout << "base2";}private: Member m;};class Derived:public Base2, public Base1{public: Derived(){std::cout << "derived";}}int main(){Derived d; return 0;}输出结果是: member //由程序员定义的 Base2::Base2() 被扩展base2 //由此可见, 调用顺序由继承顺序有关member base1derived //编译器扩展的代码结束, user code 开始运行前四段代码是编译器在用户定义的 constructor 代码中, std... 之前插入的调用 base constructor 的代码产生的结果, 按照继承的顺序调用相应的 constructor. 3. 带有 Virtual Function 的 Class在带有 virtual function 的 class 中, 如果缺少合适的 constructor, 编译器会进行两个扩张:1) 一个 virtual function table 会被创建出来, 内放 class 的 virtualfunction 地址2) 在每一个 class object 中, 一个额外的 pointer member(即 vptr) 会被创建出来, 内含相关的 vtbl 地址所以编译器会产生一个 default constructor 来初始化 vtbl 与 vptr 4. 带有Virtual Base Class 的 Class考察以下代码:struct X{int i;};struct A:public virtual X{int j;};struct B public virtual X{int k;};struct C:public A, public B{double d;} void Foo(const A *pa){pa->i = 1024;}int main(){ Foo(new A);Foo(new C);}编译器无法确定 Foo() 中 _i 的实际 _i 移动的位置, 因为 pa 可以改变, 要延迟到执行期才能固定下来, 因此此动作要通过存取 virtual base class 的相关指针来完成, 因此编译器实际可能做的事情是把函数扩充为:void Foo()(const A *pa){pa->__vbcX->i = 1024;}没错, 那么 __vbcX 就需要在 object 被建构之前被初始化, 编译器就需要为它合成一个 default constructor. 新手的误解:1) 若 class 没有定义一个 default constructor, 那么编译器就会合成一个出来;2) 编译器合成出来的 default constructor 会明确设定 class 内每一个 data member 的初始值.当然, 以上观念都是错的!