c++中類的初始化操作有四個部分組成:
1.初始化列表:所有類的非靜態資料成員都可以在這裡初始化。
2.建構函式體:函式體內進行賦值操作。
對於類的非靜態資料成員:
const型成員、引用型成員不能進行賦值操作,
類型別成員必須在進入函式體之前完成初始化,
以上情況必須在進入建構函式體之前完成初始化 。
對於類靜態資料成員:
可以在這裡修改可修改的靜態成員,但靜態成員必須已經在類外部初始化。
3.類外初始化:除乙個特例外,所有類static資料成員必須在這裡初始化,
特例是類static const int資料成員可以在這裡初始化,也可以在成員的宣告處初始化
4.類中宣告時直接初始化:static const int、對於c++11允許變數在這裡初始化
c++類的初始化的全過程:
(1)靜態成員初始化階段:所有類的靜態成員應該都是在這個階段初始化的。
需要注意的是2點,一是初始化語句不再需要static關鍵字。
二是語句的執行順序就是初始化順序。
另外需要注意的是,這些靜態成員的初始化在任何類體例項被建立前就已經完成了。
(2)非靜態成員初始化階段:
當程式在堆上或者棧上構建例項的時候,
第一步首先是向作業系統申請記憶體,初始化列表是在記憶體申請成功後才開始工作的。
然後,根據非靜態成員在類中的宣告順序結合初始化列表開始執行如下操作:
1.如果該成員沒有出現在初始化列表中:
1)如果是內建非const且非引用型別,不設定初值
2)如果是const型別,報錯,必須在這裡給定初值
3)如果是引用型別,報錯,必須在這裡給定初值
4)如果是class型別,就呼叫預設建構函式,進行初始化操作(沒有預設建構函式時必須由初始化列表提供,否則報錯)
2.如果該成員出現在初始化列表中:
1)如果是內建型別,就按初始化列表指定的值設定初值
2)如果是const型別,就按初始化列表指定的值設定初值
3)如果是引用型別,就按初始化列表指定的值設定初值
4)如果是class型別,就呼叫初始化列表指定的建構函式進行初始化操作
(3)進入建構函式體內賦值階段:
根據建構函式的函式體進行賦值操作,或者修改操作,
在這裡,靜態和非靜態資料都可以賦值和修改
總結:建構函式體內,通過賦值操作對成員變數進行修改,
前提是,進入建構函式之前,所有成員變數必須完成初始化(非const、非引用的內建型別變數除外)。
另外補充2個小點:
(1)初始化列表的使用可以提高效能
對於類型別成員,正常情況下,
在進入建構函式體內之前已經呼叫預設建構函式完成初始化,
在建構函式體內再進行賦值操作時,
那麼一共呼叫了一次預設建構函式和一次賦值操作符過載函式。
但是,當需要初始化的成員變數較多且為內建變數時,這時在多個建構函式裡都要去重複寫這些初始化列表時,
將顯得**很臃腫,可以用乙個函式去實現這些賦值過程,然後在每個建構函式裡面呼叫該函式即可。
(2)成員是按照他們在類中出現的順序進行初始化的,而不是按照他們在初始化列表出現的順序初始化的
從初始化列表和建構函式談C 的初始化機制
綜合而言,c 中類的初始化操作有四個部分組成 1.初始化列表 所有類非靜態資料成員都可以在這裡初始化,所有類靜態資料成員都不能在這裡初始化2.建構函式體 對於類非靜態資料成員 const型成員不能在這裡初始化 引用型成員不能在這裡初始化 沒有預設建構函式的成員不能在這裡初始化 對於類靜態資料成員 可...
c 建構函式中初始化列表的作用和機制
c 中建構函式有初始化列表,目的是用於變數的初始化。class a 基類初始化成員變數 protected int a class b public a 派生類不能初始化基類成員變數 這樣是正確的 includeusingnamespace std class a class b public a ...
C各種變數的儲存機制 作用域規則以及初始化
本文只作為個人防止忘記,作為基礎資料來查閱所用。一 變數型別 externel和internal簡介 internel用於描述定義在函式內部的函式變元和變數。外部變數在函式外部定義,故可以在很多函式中使用。由於c語言不允許在乙個函式中定義其他函式,因此函式本身是外部的。預設情況下,外部變數和函式具有...