條款 04:確定對象被使用前已被初始化
Make sure that objects are initialized before thre’re used.
c++ 不保證下面語境初始化
int x;
class Point
{
int x, y;
};
Point p;
某些語境會被初始化爲0,某些語境不能保證。
一般的,如果是 C part of C++,而且初始化會招致運行期成本,那麼就不保證初始化。non-C part of C++ 又有不同。
所以 array 不保證初始化內容 而 vector 保證。
使用 member initialization list(成員初值列)初始化成員
A::A(const std::string& name, const std::string& Address)
{
theName = name;
theAddress = Address;
}
A::A(const std::string& name, const std::string& Address)
: theName(name)
, theAddress(Address)
{}
第一段中,會先調用 default 構造函數爲 theName 和 theAddress 賦初值,再使用 copy assignment 對其賦值
第二段中,直接使用 copy 構造爲 theName 和 theAddress 賦值。
一般情況下,下者更優。對於內置類型成本相同,但爲了一致性相同最好也用成員初值列。
當繼承層次過多,成員初值列導致代碼大量重複時,可以考慮將性能影響少的初始化移至專門的初始化函數(通常是private)供構造函數調用
C++ 成員初始化順序
- base class 優於 derived class
- 成員變量按照申明順序初始化,與成員初值列順序無關
不同編譯單元的 non-local static 對象初始化次序
- C++ 對於不同編譯單元的 non-local static 對象初始化次序無明確定義。這很難,最常見的,多個編譯單元內的 non-local static 對象經由“模板隱式具現化(implict template instantiations)”形成。
- 一個簡單的解決方法,可以把 non-local static 對象搬到專屬函數,作爲 local static 對象,該函數返回 reference 指向該對象,用戶直接調用函數而非對象,最常見的就是單例模式的實現。
- 該方法的理論基礎是:C++ 保證函數內的 local-static 對象會在“訪問函數”、“首次遇上對象定義式”時被初始化