1.手工初始化所以内置类型:
这一条很好理解,对于int,enum等内置类型,在使用前一定要初始化。
2.对于类类型等用户自定义的对象,使用成员初值列初始化所有的对象:
1 using namespace std;
2
3 class PhoneNumber{};
4 class Customer
5 {
6 public:
7 Customer(const string& name, const string& address,
8 const PhoneNumber& phone);
9 private:
10 string theName;
11 string theAddress;
12 PhoneNumber thePhone;
13 int usedTimes;
14 }
2
3 class PhoneNumber{};
4 class Customer
5 {
6 public:
7 Customer(const string& name, const string& address,
8 const PhoneNumber& phone);
9 private:
10 string theName;
11 string theAddress;
12 PhoneNumber thePhone;
13 int usedTimes;
14 }
对于Customer类的构造函数定义,一般我们会这么写:
1 Customer::Customer(const string& name, const string& address, const PhoneNumber& phone)
2 {
3 theName = name; //这些都是赋值
4 theAddress = address;//而不是初始化
5 thePhone = phone;
6 usedTimes = 0;
7 }
2 {
3 theName = name; //这些都是赋值
4 theAddress = address;//而不是初始化
5 thePhone = phone;
6 usedTimes = 0;
7 }
可是,在c++中,对不是内置型的对象的初始化都发生在进入构造函数之前,也就是说,在进行theName = name;赋值之前,theName就已经进行了初始化了,这个过程调用自己的默认构造函数。
紧接着有立刻进行了赋值操作,这样会造成额外的浪费,所以我们可以这样写构造函数:
1 Customer::Customer(const string& name, const string& address, const PhoneNumber& phone)
2 :theName(name),//成员初始化列
3 theAddress(address),
4 thePhone(phone),
5 usedTimes(0)//内置类型也一并初始化
6 {
7 }
2 :theName(name),//成员初始化列
3 theAddress(address),
4 thePhone(phone),
5 usedTimes(0)//内置类型也一并初始化
6 {
7 }
使用了成员初始化列的方法,在进入构造函数体之前就进行了初始化,减少了赋值的开销,同时为了保持一致性,将内置类型也一并进行了初始化。
还有一点要记住:在成员初始化列中对变量的初始化次序是按照变量声明的次序的,也就是说,即使将上面的次序任意改变,也改变不了初始化次序,所以我们要尽可能地按照使用的顺序来声明变量!
3.在多个编译单元内的non-local static对象的初始化次序问题:
non-local static对象表示在程序执行过程中一直存在的对象,像类中声明的static变量,全局变量,而在普通函数中声明的static变量称为local static变量。
那么当有多个不同的编译单元(即存在于不同的文件中)时,对这些non-local static对象的初始化次序,在c++中,是不确定的,而且也没法确定!
当两个或多个文件中的non-local static对象发生关联时,问题就出现了。
解决方法就是使用了设计模式中的:Singleton单件模式,将对non-local static的访问移到函数中,将其转变为local static变量,确保其被初始化了再使用。
梦想与现实的落差,就是我们离成功的距离~