C++之初始化問題

轉載自:http://www.cnblogs.com/kunhu/p/3593635.html

首先,我們應該明確的是在C++中初始化不是賦值,因爲初始化是必要的,如果讀取了未初始化的值將會導致不明確的行爲。初始化指創建變量並且給它賦初值,而賦值則是擦除對象的當前值並用新值代替。C++支持兩種初始化變量的方式:複製初始化和直接初始化

int ival(1000);//直接初始化是將初始化式放在括號裏
int ival=1000;//複製初始化是用等號(=)

那麼這兩種方式有什麼區別呢?我們可以這樣認爲,對於內置類型來說,複製初始化和直接初始化幾乎沒有差別,對於類類型來講,當創建類類型對象時,初始化的複製形式和直接形式有所不同:直接初始化直接調用與實參匹配的構造函數,複製初始化總是調用複製構造函數。複製初始化首先使用指定構造函數創建一個臨時對象,然後使用複製構造函數將那個臨時對象複製到正在創建的對象:

string strVal1=”2014”;//編譯器首先調用接受一個字符串形參的string構造函數,創建一個臨時對象,然後,編譯器使用

string複製構造函數將strVal1初始化爲那個臨時對象的副本

string strVal2(“2014”);//直接調用string類中匹配的構造函數

string strVal3 = string();//先使用默認構造函數創建一個臨時對象,使用複製構造函數將那個臨時對象複製到正在創建的對象

string strVal4;//直接運行strVal4的默認構造函數
其次,講講變量的初始化規則:
內置類型變量的初始化是否自動初始化取決於變量定義的位置,在函數體外定義的變量都初始化成0,在函數體內定義的內置變量不進行自動初始化,因此,實際編程中,建議每個內置類型的對象都要初始化,雖然有時候這樣做並不總是必須的。類類型的初始化與它的默認構造函數是否存在有關,只要它有默認構造函數,則不管變量在那裏定義,我們都可以不提供初始化式,相反,我們則需要每個定義都必須提供顯式的初始化式,如:

string emptyStr;//因爲類中定義了默認構造函數來初始化string變量爲空字符串
接下來,我們來看看關於類類型的兩種構造函數的寫法
法一:
TestOne::TestOne(const std::string &name,const::string & address,
const std::list& phones)
{
theName=name;
theAddress=address;//注意這些都是賦值,而非初始化
thePhones=phones;
}
法二:
TestTwo::TestTwo(const std::string &name,const::string & address,
const std::list& phones)
:theName(name),
theAddress(address),//現在這些都是初始化
thePhones(phones)
{ }//現在,構造函數體不必有任何動作

這兩種方法都可以滿足我們的需要,但是效果是不一樣的。
C++中規定,對象的成員變量的初始化動作發生在進入構造函數本體之前,在法一中,theName,theAddress,thePhone這些成員的初始化發生的時間是在這些成員的默認構造函數被自動調用之時,也就是它們真正被初始化的時候,因此,它們發生的時間比進入當前構造函數的時間更早。因此,法一相當於對這些已經被默認構造函數初始化的成員變量再次進行賦值,默認構造函數做了無用功。而法二,則是直接就通過成員的構造函數來初始化的,一步到位。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章