1. 程式人生 > 其它 >很淺的談C++初始化列表

很淺的談C++初始化列表

技術標籤:c++程式語言

首先這裡都是一家之言自我高潮,很可能出現錯誤,如果有幸大佬肯看並且發現錯誤請予以指正避免誤人子弟。我寫的這些東西純屬自嗨,請勿輕信。

初始化列表,是C++建構函式專屬的一個語法,用於初始化成員變數。
那麼用它初始化 與 在建構函式體裡邊直接給成員賦值有什麼區別?
我認為,想理解這一點,關鍵是理解初始化和賦值不是一回事
只要理清了什麼是初始化,一切都好說

什麼叫初始化?

我常聽說:初始化就是給變數賦初值。純屬屁話。什麼叫初值?為什麼非要賦個初值?

我的理解是,你建立一個變數,它開闢了一塊記憶體空間。開闢空間後,這空間裡邊必須有點東西,你不能什麼也不放,這空間不能是”真空“。這時候往裡邊放某個值,就叫初始化。你可以利用一些語法自己主動的初始化,如果你不手動初始化,此時要麼變數自己自動的初始化,要麼就報錯。

比如你 int a; 沒有手動的去初始化它,但是他指代的記憶體空間裡也不是空的,而是自動的被初始化了。在C++中,區域性變數自動初始化的就是隨機的int值。你int *p;你沒手動初始化直接用了,這個指標變數裡邊也是個隨機的地址值。野指標就這麼來的。

或者說,變數需要有個值才能被成功的建立,此時為了能成功建立變數而做出的‘賦值“行為就叫初始化。

我們看看定義一個普普通通的變數時,常用的手動初始化的語法是什麼?就是

int a=10;

這看起來就像只是在宣告時順便給變數賦個值。所以大夥把初始化和賦值整混了。其實這種初始化方法叫做拷貝初始化,是把等號右側的東西複製給新建立的變數讓他初始化。

其實最正經的初始化方法應該是這樣的

int a(10);

用小括號這種就叫直接初始化。
初始化其實有好幾種寫法。這裡就不多說了,因為很淺。

現在看看初始化列表

人都說,建構函式的執行過程分為兩步:先是初始化階段,後計算階段。
計算階段就是執行函式體內容。
初始化階段乾的是什麼?我們想著,先把成員變數先給建立好,準備好,然後再考慮往下執行建構函式體裡的程式碼。這看起來很合乎邏輯,我函式體可不就是要用成員變數,沒發麵和餡你包什麼餃子啊。可是你要建立變數,你得初始化啊。初始化階段就幹這個的。

那麼大夥研究的挺好,在執行這個函式體之前,你得先把我這個成員變數給建立,初始化嘍。初始化你得給他一個值啊?因此就又分成兩種情況。如果你寫了初始化列表,寫誰誰誰,你是什麼什麼值,大夥一瞧得咧,就照你說的來,我就初始化這個值。這是好的情況,誰也沒問題。

那,你要是沒寫初始化列表吶?平時的成員變數倒好說,人家會自動初始化。本來嗎,你宣告一個變數不給他初始化他就隨便找個隨機的值裝上。然後你在建構函式體裡,樂意賦個值,就把他們改了。

可其中一個問題是,你讓那const 常量,和那引用怎麼辦?這倆爺,必須要在定義時手動初始化,而且初始化完了就不許改。你沒寫初始化列表他們倆人沒轍啊。怎麼辦?簡單!直接完蛋。報錯。

所以說,因為const常量和引用的初始化必須人為控制,所以要寫在初始化列表裡。這是用初始化列表的其中一個原因。

有人說那不對啊,你平時,怎麼定義引用,怎麼定義常量啊?不就int &a = b;你直接這麼寫不就得了?非那麼大勁幹嘛?
誰吃飽了撐的費這麼大勁啊。那不是類成員變數定義時不準直接寫賦值(C++11之前)嗎。所以你在類體裡定義成員變數時你只能寫int &a,你不能寫那個“=b” 啊。

這個初始化列表還有其他不得不用的情況,網上不乏相關資料,這裡就不寫了。