类的初始化

来源:互联网 发布:php考试系统 编辑:程序博客网 时间:2024/06/13 14:06

类的初始化通产有3种类型:使用初始化列表,在构造函数体中赋值,以及使用默认构造函数。

先说前两种:

初始化列表与在构造函数体中赋值的区别在哪里呢?主要有两点:

第一,有的成员不能使用函数体中的“=”初始化。这其实就是初始化与赋值的区别:比如比如const 成员,引用类型,以及没有定义默认构造函数的类,它们都必须在定义时初始化,而不能赋值,这时候我们的初始化列表就派上用场了。

第二,初始化的顺序不同。初始化的顺序看起来似乎无关紧要,但是如果一个数据的初始化依赖于另一个,就很重要。举一个不恰当的例子:

//构造函数//初始化列表中先试图先初始化ival1,再用ival1初始化ival2NoName(int i1):ival1(i1),ival2(ival1){}string *pstring;//先定义ival2,在定义ival1int ival2;int ival1;


如果调用NoName nm2(2);结果是ival1 = 2,ival2;的值不确定。如果调用NoName nm2(2);结果是ival1 = 2,ival2;的值不确定。如果调用NoName nm2(2);结果是ival1 = 2,ival2;的值不确定。这是因为初始化的顺序不是初始化列表的顺序,而是定义类成员的顺序!所以实际上,会用不确定的值初始化ival2,然后再用2初始化ival1.

而使用函数体初始化就避免了这个问题,哪个语句在前,先赋值初始化谁:

NoName(int i1){ival1 = i1;ival2 = ival1;}


这样两个成员都被初始化为2了。这样两个成员都被初始化为2了。这样两个成员都被初始化为2了。

说完了前两种,再看看默认构造函数:

如果定义一个类时没有提供初始化式,则使用默认构造函数。但如果这个类哪怕定义了一个构造函数(即使它缺陷很多),系统也不会使用默认的构造函数。

如果没有这个类定义构造函数,则会为它合成一个默认的构造函数,合成规则与变量的初始化规则相同:对于类成员,通过运行它的默认构造函数来初始化;对于内置或者符合类型的成员,因为编译器应该只对全局的这种变量初始化,而类的成员不是全局的,所以这样就会初始化失败。

通常情况下,应该为一个类定义一个默认构造函数,这样可以省去定义对象时的许多麻烦,尤其是遇到类的成员是另一个类类型时,如果这个类类型没有定义默认构造函数,那么定义这个类的构造函数时,都要为这个类的那个类类型的成员的构造函数传递参数。