定义
每个类都分别定义了它的对象被初始化的方式,类通过一个或多个特殊的函数控制其对象的初始化过程,而这些函数称为构造函数(constructor)。
构造函数的任务:初始化类对象的数据成员
构造函数被调用的时机:无论何时只要类的对象被创建,构造函数就会被调用。
特征
1.构造函数的名字和类名相同
2.无返回类型,无返回值
3.不能被声明为const
型:当我们在创建一个const
对象时,直至构造函数完成初始化过程,对象才真正意义上获得其“常量”属性。因此,构造函数在const
对象的构造过程中可以向其写值
4.发生对象实例化时,构造函数会被编译器自动调用
5.若类中未显式定义构造函数,C++编译器会自动隐式生成默认构造函数。反之,若类中显式定义了构造函数,则默认构造函数不再生成。
6.无参构造函数和全缺省的构造函数都称为默认构造函数,且默认构造函数只能存在一个。【无参构造函数和全缺省的构造函数,我们没写编译器默认生成的构造函数,都可以认为是默认构造函数】
7.其他属性基本与其他函数保持一致,包括重载【同样要求参数列表不同】。
默认构造函数
我们已经知道当类中未显式定义构造函数时,编译器会自动隐式生成默认构造函数,默认构造函数无需任何实参。
对于大多数类来说,默认构造函数按如下规则初始化类的数据成员:
· 如果存在类内的初始值,则用它来初始化成员。
· 否则,默认初始化该成员
既然我们不写构造函数,编译器会自动生成默认构造函数完成对象的初始化,那么为什么我们还要写构造函数?
某些类不能依赖于自动生成的默认构造函数:默认构造函数只适合非常简单的类。对于一个普通的类来说,我们必须定义该类的默认构造函数,至于为什么,有以下三个原因:
1. 编译器只会在发现类中不存在任何构造函数的情况下才会生成默认构造函数。一旦我们定义了一些其他的构造函数,除非我们再定义一个默认的构造函数,否则该类将不存在默认构造函数。该规则的依据是:如果一个类在某种情况下需要控制对象初始化,则该类可能在所有情况下都需要控制。
2. 对于某些类来说,默认构造函数会执行错误的操作。若某个类中含有内置类型或复合类型成员(如数组和指针),只有当这些成员全都被赋予了类内的初始值,该类才适合于使用默认构造函数。否则创建类的对象时,我们将得到未定义的值。
3. 有时编译器不能为某些类合成默认构造函数。例如,一个类中包含另一个类类型的成员,且该成员的类型没有默认构造函数。对于这种类,如果我们不定义其函数,那么它将没有可用的默认构造函数。
=default
如下:
Test() = default;
首先,该构造函数不接受任何实参,所以它是一个默认构造函数,之所以定义这样一个构造函数,是因为我们既需要其他形式(带参)的构造函数,也需要默认的构造函数。在C++11新标准中,如果我们需要默认的行为,则可以在参数列表之后写上=default
去要求编译器生成构造函数。
建议
1.最好令构造函数初始值的顺序与成员声明的顺序保持一致,且在可能的情况下,尽量避免用某些成员初始化其他成员。
2.使用构造函数初始值:在很多类中,初始化与赋值的区别事关底层效率问题:前者直接初始化数据成员,后者则是先初始化再赋值,另外一个重要原因在于一些数据成员必须被初始化。——【C++ Primer】