首先,本篇文章只讲 “默认构造函数”,即如你所知,默认构造函数是不带参数的构造函数。
编译器会在 适当的时候 为class合成一个默认构造函数 ~~
先问以下两个问题:
编译器会为任何没有声明构造函数的class,合成默认构造函数?? 错!!!
合成的默认构造函数会显示设定class内的每一个data member的默认值?? 错!!!
class Base { public: int x; int getX() const {return x;}; }; int main() { Base b; cout << b.getX() << endl; return 0; }
结果不如人意,getX的输出值完全是随机的。
编译器的动作,是仅限于自己的责任,类的设计者如果需要为类的所有成员进行初始化,那么自己动手吧!!
编译器的动作是隐式的,因此,了解什么时候算是 “适当的时候”??
以下的4个方面是编译器的所谓的适当的时候。。。
1 带有“默认构造函数”的类成员对象。
就是说,如果类A的一个对象a作为类B的成员变量,并且类B没有定义构造函数,但是类A有自己的默认构造函数,那么,在定义类B的对象时,编译器会为类B合成一个默认构造函数。因为在创建类B的对象时,期间必须调用类A的默认构造函数初始化a。
例如:
执行结果为:
可以看到,成员变量b2和b的默认构造函数被调用,并且是按照其声明次序。
2 带有默认构造函数的基类
就是说。如果类Derived继承自类Base,但是Base类没有定义默认构造函数的话,分两种情况:
如果这个Derived类没有定义构造函数,那么编译器必定会为其合成一个,因为此时的默认构造函数将不是trivial的,因此必须将它合成,用于初始化基类。
如果Derived类定义了自己版本的构造函数,这其中并没有默认构造函数,那么在这些定义的构造函数调用之前,还是会调用基类的默认构造函数。
如下:
执行结果为:
可以看到,在Derived类中并没有默认构造函数,但是当我们使用 "以int作为参数的构造函数"时,其基类的默认构造函数被调用(按声明次序),调用完成之后,如果还有成员对象,再调用该类的默认构造函数(如此处的Member).
3 带有 ”虚函数“的类
也就是说,如果一个class继承一个虚函数,或者是一个类的继承体系中含有 virtual继承。如果用户没有定义构造函数,那么编译器会合成。
如下: