危害:讀取未初始化的值會導致不明確甚至是半隨機化的行為。
最佳處理辦法:永遠在使用對象之前先將它初始化;確保每一個構造函數都將對象的每一個成員初始化。
1 注意區分賦值和初始化:
從初始化的角度而言,這不是一個最佳的處理辦法。雖然這會讓對象的指最終為你期望的值,但是實際上,對象的成員變量的初始化動作發生在進入構造函數本體之前。而在構造函數本體之內,不是被初始化,而是被賦值。
2 較佳的寫法:使用成員變量初始化列表
結果和上一個的最終結果相同,但是效率較高。
規定:總是在初值列表中列出所有成員變量,以免遺漏需要初始化的成員變量。即,總使用成員初始化列表。
一個特例再次印證了上句的價值:如果成員變量是const或reference,它們就一定需要初值,不能被賦值。
3 成員初始化次序:
一般地:
base classes更早於其derived classes被初始化,而class的成員變量總是以其聲明次序被初始化。
不同編譯單元內定義的non-local static對象的初始化次序
global對象定義於namespace作用域內的對象在classes內、在file作用域內被聲明為static的對象local static對象,指在函數內被聲明為static的對象。
C++對“不同編譯單元內的non-local static對象”的初始化相對次序並無明確定義。原因:
決定它們的初始化次序相當困難,甚至是無解的。解決:
reference-returning函數(示例如下)原理:
C++保證,函數內的local static對象會在該函數被調用期間首次遇上該對象的定義式時被初始化。 所以以函數調用替換直接的對象訪問,就保證獲得一個已經初始化的對象的引用。Demo: 可能會發生初始化次序問題的版本:
a.cpp
b.cpp