首页 > 代码库 > C++基础知识—关于默认构造函数的一切
C++基础知识—关于默认构造函数的一切
C++条款—关于默认构造函数的一切
默认构造函数(defaultconstructor):
默认构造函数是在未提供显示初始值时,用来创建对象的构造函数。如果没有提供任何构造函数,则C++将自动提供默认构造函数,默认构造函数没有参数,因为声明中不包含值。同时,当且仅当没有定义构造函数时,编译器才会提供默认构造函数。为类定义了构造函数后,程序员就必须为它提供默认构造函数,如果提供了非默认构造函数,但没有提供默认构造函数,则在初始化对象时调用默认构造函数是会出错的:
Stack ww;// 错误
定义默认构造函数有两种方法,一种是让所有的参数都有默认值,一种是通过函数重载的方式来定义另一个构造函数---一个没有参数的构造函数。
总而言之,如果程序没有提供任何构造函数,那么编译器会为程序定义一个默认构造函数;否则,必须自己提供默认构造寒素。默认构造函数可以没有任何参数,如果有,则必须给所有参数都提供默认值。
明白了这些之后,在进入深层次的分析。
什么时候编译器为合成一个default constructor.当编译器需要它的时候!被合成出来的constructor值执行编译器所需要的行动。在没有任何构造函数的类,在进行初始化此类的对象时,编译器合成了一个default constructor,但是这个合成出来的也不会为成员变量进行初始化。如果想为类中的成员变量进行初始化,就必须主动提供一个显示的default constructor.
所以,就产生了这么一说:对于classX,如果没有任何用户定义的构造函数,那么会有一个default constuctor被暗中(implicitly)申明出来…..一个被安装声明出来的default constructor将是一个trivial(无用)的构造函数…..
而一个nontrivial defaultconstructor就是编译器所需要的那种,有四种情况编译器会合成nontrivial default constructor,下面就讨论有四种情况下编译器会合成nontrivialdefault constructor。只有在编译器需要的时候编译器才有合成default constructor。
1、“带有defaultconstructor”的member class object(就是一个类中的一个成员具有defalult constructor)
如果一个class没有任何constructor,但它内含一个memberobject,而后者有default constructor,那么这个class的implicit default construct即使nontrivial,编译器需要为此class合成出一个defaultconstructor.注意,这个class没有任何constuctor是第一个前提,如果这个class有任何一个构造函数,那么编译器就不会合成default constructor.同时他们是以内联的形式被合成的。合成的默认构造函数只负责初始化具有默认构造函数的member class object.
同时,如果用户定义了默认构造函数,在这个默认构造函数中没有显示的调用对象成员的默认构造函数,那么这个对象成员的默认构造函数会被合成到这个定义的默认构造函数的。
2、“带有defaultconstructor”的Base class(从具有默认构造函数继承的类)
如果没有任何constructors的class派生自一个“带有defaultconstructor”的base class,那么这个derived class的default constructor会被视为nontiivaial,并因此需要合成出来。
在这种情况下,如果设计者提供多个constructors,但是其中都没有定义default constructor?在这些字自定义的构造函数内,如果没有调用父类的构造函数来初始化父类成员,那么父类的default construcots会被添加进去。它不会合成一个新的default constructor,这是因为已经有了用户自定义的构造函数存在(看最开始的部分就可以明白)的缘故。如果这个子类同时存在着“带有default constructor”的member class objects,那么defalult constructor也会被调用----在所有base class constructor被调用之后(为什么呢?因为有几成关系的都是先调用子类的构造函数,然后才会初始化子类的成员)
3、“带有一个virtualfunction”的class
不管是继承还是声明,只要在此类中存在了virtual function,同时缺乏用户自定义的构造函数,编译器会合成一个default constructor
4、“带有一个virtual baseclass”的class
如果没有任何用户自定义的函数,但是这个类继承了virtual base class,那么编译器会合成一个default constructor
总结:上述四种情况下,编译器必须为没有生命构造函数的类合成一个default constructor,C++标准把那些合成物成为隐式有用默认构造函数(implicitnontrivial default constructors),但是合成出来的构造函数只能满足编译器的需要。他们能完成任务,是借着“调用成员对象或基类的default constructor”或是“为灭一个对象初始化其虚拟函数机制或虚基类机制”而完成。至于没有存在那四种情况而又没有任何构造函数的类,我们说他们拥有的是implicit trivial default constructor(隐式无用默认构造函数)。
在合成的defaultconstructor中,只有base class subobjects和member class objects会被初始化。所有其他的成员都不会被初始化。这些初始化操作对程序而言或许有需要,但对编译器则并非必要。
C++基础知识—关于默认构造函数的一切