C 初始化列表深入探索

2021-10-03 18:07:45 字數 1643 閱讀 6589

1. 當初始化乙個引用的成員

2. 當初始化乙個const的成員

3. 當呼叫乙個基類的物件(該類繼承於基類),且基類有含有引數的建構函式時

4. 當呼叫乙個類的物件成員時,且該物件成員所在的類有含有引數的建構函式時

通過下面的**,可以更詳細的說明這四種情況:

#include using namespace std;

class b

};class base

};class a : public base

};int main()

那麼以上這四種情況是必須要用初始化列表的方式去初始化的,如果在函式體中去初始化會報錯。

最主要的優勢就是可以提高執行效率,尤其是對含有類物件的成員時,效率會有很大的提公升,下面也用乙個示例來證明一下,首先我們先將初始化寫在函式體內,觀察一下結果:

#include using namespace std;

class b

b& operator=(const b& tmp)

~b()

};class a

};int main()

上面的**構建了乙個類b,並在類a中定義了乙個類b的物件,然後並在函式體中對m_mx進行了初始化,執行結果如下圖所示:

我們暫且先不判斷放在函式體中的初始化的好壞,我們先來使用初始化列表的方式對其初始化一下看看結果是什麼樣的,初始化列表方法執行結果:

可以發現少了三行**,那麼我們站在編譯器的角度來分析一下具體原因,其實通過多的那三行輸出,就可以發現編譯器為我們例項化了乙個臨時物件,並對其進行了初始化,然後再將結果通過賦值建構函式給了m_mx物件,然後再析構掉臨時物件,那麼編譯器在背後實現的**如下:

class a 

};

所輸出的5行語句就是這麼來的,其中有兩行不會呼叫預設建構函式這裡就不解釋了,不清楚的可以看這篇部落格:傳送門,由此可見,m_mx=100這一行**被轉換成了這麼多行,我們再來看看使用初始化列表的方法來初始化的話,編譯器是怎麼做的:

class a 

};

顯然這裡編譯器直接呼叫建構函式進行初始化就可以了,免去了多餘的例項化臨時物件,因此效率上會有大的提公升,那麼對於一些簡單的成員進行初始化的時候(比如int型別),其實二者沒有太大的區別,但是還是建議都是用初始化列表進行初始化。

1. 雖然初始化列表的寫法比較奇怪,但是站在編譯器的角度來看,實際上初始化列表的**還是被安插在函式體中去執行

2.當自己在函式體中已經寫了一部分的**,那麼初始化列表的**是優先於自己寫的**執行的。

3.對於物件成員的初始化順序,是按照物件成員的定義順序執行的,而不是按照初始化列表的順序執行的。

初始化列表(深入探索建構函式)

一 類的成員變數有兩種初始化方式 一是建構函式體內進行賦值 二是初始化列表進行初始化。初始化列表以乙個冒號開始,以逗號分隔資料列表,每乙個元素要初始化的值都在括號中。class date private int year int month int day 二 初始化列表更高效 嘗試執行以下 在上面...

c 初始化列表

與其他函式不同,建構函式除了有名字,引數列表和函式體之外,還可以有初始化列表,初始化列表以冒號開頭,後跟一系列以逗號分隔的初始化字段。struct foo 初始化列表 建構函式的兩個執行階段 從概念上來講,建構函式的執行可以分成兩個階段,初始化階段和計算階段,初始化階段先於計算階段 初始化階段 所有...

C 初始化列表

與其他函式不同,建構函式除了有名字,引數列表和函式體之外,還可以有初始化列表,初始化列表以冒號開頭,後跟一系列以逗號分隔的初始化字段。在c 中,struct和class的唯一區別是預設的克訪問性不同,而這裡我們不考慮訪問性的問題,所以下面的 都以struct來演示。struct foo 初始化列表 ...