我自己在寫代碼的時(shí)候也經(jīng)常會遇到忘記初始化某對象的問題,而且這些錯(cuò)誤比較難以調(diào)試,Meyers提出了一些避免這些錯(cuò)誤的解決方法:
1.手工初始化所以內(nèi)置類型:
這一條很好理解,對于int,enum等內(nèi)置類型。
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 }
對于Customer類的構(gòu)造函數(shù)定義,一般我們會這么寫:
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 }
可是,在c++中,對不是內(nèi)置型的對象的初始化都發(fā)生在進(jìn)入構(gòu)造函數(shù)之前,也就是說,在進(jìn)行theName = name;賦值之前,theName就已經(jīng)進(jìn)行了初始化了,這個(gè)過程調(diào)用自己的默認(rèn)構(gòu)造函數(shù)。
緊接著有立刻進(jìn)行了賦值操作,這樣會造成額外的浪費(fèi),所以我們可以這樣寫構(gòu)造函數(shù):
1 Customer::Customer(const string& name, const string& address, const PhoneNumber& phone)
2 :theName(name),//成員初始化列
3 theAddress(address),
4 thePhone(phone),
5 usedTimes(0)//內(nèi)置類型也一并初始化
6 {
7 }
使用了成員初始化列的方法,在進(jìn)入構(gòu)造函數(shù)體之前就進(jìn)行了初始化,減少了賦值的開銷,同時(shí)為了保持一致性,將內(nèi)置類型也一并進(jìn)行了初始化。
還有一點(diǎn)要記?。涸诔蓡T初始化列中對變量的初始化次序是按照變量聲明的次序的,也就是說,即使將上面的次序任意改變,也改變不了初始化次序,所以我們要盡可能地按照使用的順序來聲明變量!
3.在多個(gè)編譯單元內(nèi)的non-local static對象的初始化次序問題:
non-local static對象表示在程序執(zhí)行過程中一直存在的對象,像類中聲明的static變量,全局變量,而在普通函數(shù)中聲明的static變量稱為local static變量。
那么當(dāng)有多個(gè)不同的編譯單元(即存在于不同的文件中)時(shí),對這些non-local static對象的初始化次序,在c++中,是不確定的,而且也沒法確定!
當(dāng)兩個(gè)或多個(gè)文件中的non-local static對象發(fā)生關(guān)聯(lián)時(shí),問題就出現(xiàn)了。
解決方法就是使用了設(shè)計(jì)模式中的:Singleton單件模式,將對non-local static的訪問移到函數(shù)中,將其轉(zhuǎn)變?yōu)閘ocal static變量,確保其被初始化了再使用。
如果是多個(gè)non-local static對象互相之間都有關(guān)聯(lián),那對不起,是設(shè)計(jì)出了問題。
1.手工初始化所以內(nèi)置類型:
這一條很好理解,對于int,enum等內(nèi)置類型。
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 }
對于Customer類的構(gòu)造函數(shù)定義,一般我們會這么寫:
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 }
可是,在c++中,對不是內(nèi)置型的對象的初始化都發(fā)生在進(jìn)入構(gòu)造函數(shù)之前,也就是說,在進(jìn)行theName = name;賦值之前,theName就已經(jīng)進(jìn)行了初始化了,這個(gè)過程調(diào)用自己的默認(rèn)構(gòu)造函數(shù)。
緊接著有立刻進(jìn)行了賦值操作,這樣會造成額外的浪費(fèi),所以我們可以這樣寫構(gòu)造函數(shù):
1 Customer::Customer(const string& name, const string& address, const PhoneNumber& phone)
2 :theName(name),//成員初始化列
3 theAddress(address),
4 thePhone(phone),
5 usedTimes(0)//內(nèi)置類型也一并初始化
6 {
7 }
使用了成員初始化列的方法,在進(jìn)入構(gòu)造函數(shù)體之前就進(jìn)行了初始化,減少了賦值的開銷,同時(shí)為了保持一致性,將內(nèi)置類型也一并進(jìn)行了初始化。
還有一點(diǎn)要記?。涸诔蓡T初始化列中對變量的初始化次序是按照變量聲明的次序的,也就是說,即使將上面的次序任意改變,也改變不了初始化次序,所以我們要盡可能地按照使用的順序來聲明變量!
3.在多個(gè)編譯單元內(nèi)的non-local static對象的初始化次序問題:
non-local static對象表示在程序執(zhí)行過程中一直存在的對象,像類中聲明的static變量,全局變量,而在普通函數(shù)中聲明的static變量稱為local static變量。
那么當(dāng)有多個(gè)不同的編譯單元(即存在于不同的文件中)時(shí),對這些non-local static對象的初始化次序,在c++中,是不確定的,而且也沒法確定!
當(dāng)兩個(gè)或多個(gè)文件中的non-local static對象發(fā)生關(guān)聯(lián)時(shí),問題就出現(xiàn)了。
解決方法就是使用了設(shè)計(jì)模式中的:Singleton單件模式,將對non-local static的訪問移到函數(shù)中,將其轉(zhuǎn)變?yōu)閘ocal static變量,確保其被初始化了再使用。
如果是多個(gè)non-local static對象互相之間都有關(guān)聯(lián),那對不起,是設(shè)計(jì)出了問題。