程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> Effective C++(4) 確定對象被使用前已先被初始化

Effective C++(4) 確定對象被使用前已先被初始化

編輯:C++入門知識

危害:讀取未初始化的值會導致不明確甚至是半隨機化的行為。 最佳處理辦法:永遠在使用對象之前先將它初始化;確保每一個構造函數都將對象的每一個成員初始化。

1 注意區分賦值和初始化:
\
\
從初始化的角度而言,這不是一個最佳的處理辦法。雖然這會讓對象的指最終為你期望的值,但是實際上,對象的成員變量的初始化動作發生在進入構造函數本體之前。而在構造函數本體之內,不是被初始化,而是被賦值。

2 較佳的寫法:使用成員變量初始化列表
\
\ 結果和上一個的最終結果相同,但是效率較高。
規定:總是在初值列表中列出所有成員變量,以免遺漏需要初始化的成員變量。即,總使用成員初始化列表。
一個特例再次印證了上句的價值:如果成員變量是const或reference,它們就一定需要初值,不能被賦值。

3 成員初始化次序:
一般地:

base classes更早於其derived classes被初始化,而class的成員變量總是以其聲明次序被初始化。

特別低:
不同編譯單元內定義的non-local static對象的初始化次序

解析: 1 non-local static: 包括:
global對象定義於namespace作用域內的對象在classes內、在file作用域內被聲明為static的對象
local static對象,指在函數內被聲明為static的對象。
2 編譯單元:產出單一目標文件的那些源碼。基本上可以認為是一個源碼文件加上它所包含的頭文件。
問題:
C++對“不同編譯單元內的non-local static對象”的初始化相對次序並無明確定義。
原因:
決定它們的初始化次序相當困難,甚至是無解的。
解決:
reference-returning函數(示例如下)
原理:
C++保證,函數內的local static對象會在該函數被調用期間首次遇上該對象的定義式時被初始化。 所以以函數調用替換直接的對象訪問,就保證獲得一個已經初始化的對象的引用。
Demo: 可能會發生初始化次序問題的版本:
a.cpp
\
\ b.cpp \
\


改進後的版本: \


小結: 為內置類型對象進行手工初始化,以為C++不保證初始化它們;構造函數最好使用成員變量初始化列表,其排列次序應該和它們在class中的聲明次序相同;為免除“跨編譯單元之初始化次序”問題,請以local static對象(referance returning函數)替換non-local static對象。
參考資料: 《Effective C++ 3rd》

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved