c++:類的建構函式
:下面我們先看例子
#include
using
namespace std;
class
base
private
:int m_num;
};
上邊的**,我先定義了乙個base類,並且定義了有乙個整型實參的建構函式base(int val)
class
basechild
:public base
private
:int m_num;};
intmain
(int argc,
char
*ar**)
上邊的**繼承base,定義了它的預設建構函式
並且在主函式中建立basechild的物件child
編譯報如下錯誤:
這意思是說,沒有base的預設建構函式。
結論1:如果沒有定義任何建構函式,c++編譯器會自動建立乙個預設建構函式。
結論2:如果已經定義了乙個建構函式,編譯器不會自動建立預設建構函式,只能顯式呼叫該建構函式。
在c++中,當建立乙個物件時,編譯器要保證呼叫了所有子物件的建構函式,這是c++強制要求的,也是它的乙個機制。
因為在base中沒有定義預設建構函式,只定義了乙個有整型引數的建構函式,而basechild繼承base時,又沒有顯式地指定base的建構函式,所以編譯報錯。
如果base是不可以修改的,那麼,我們用什麼辦法可以顯式的呼叫base的建構函式呢。答案就是初始化列表。
c++就為我們提供了這樣的語法。即在冒號和這個建構函式定義體的左括號之間呼叫基類建構函式或初始化本類成員,如下:
basechild()
:base(1
)
現在,再編譯程式,輕鬆通過。
當然,初始化列表還可以對類本身的資料成員進行初始化,如對basechild成員m_num進行初始化:
basechild()
:base(1
),m_num(0
)
中間要以逗號隔開。
細心的同學,可能會提問,我們平常見到的都是
int m_num = 0;
而剛剛的**是m_num(0),這是正確的,我們可以認為這就是呼叫了int型別的建構函式。類似的,new int(2)是一樣的道理。
最後,總結一下初始化列表:
1、因為初始化列表中無法直接初始化基類的資料成員,所以你需要在列表中指定基類的建構函式,如果不指定,編譯器則會呼叫基類的預設建構函式。
2、推薦使用初始化列表,它會比在函式體內初始化派生類成員更快,因為在分配記憶體後,在函式體內又多進行了一次賦值操作。
3、初始化列表並不能指定初始化的順序,正確的順序是,首先初始化基類,其次根據派生類成員宣告次序依次初始化。
c 初始化列表
與其他函式不同,建構函式除了有名字,引數列表和函式體之外,還可以有初始化列表,初始化列表以冒號開頭,後跟一系列以逗號分隔的初始化字段。struct foo 初始化列表 建構函式的兩個執行階段 從概念上來講,建構函式的執行可以分成兩個階段,初始化階段和計算階段,初始化階段先於計算階段 初始化階段 所有...
C 初始化列表
與其他函式不同,建構函式除了有名字,引數列表和函式體之外,還可以有初始化列表,初始化列表以冒號開頭,後跟一系列以逗號分隔的初始化字段。在c 中,struct和class的唯一區別是預設的克訪問性不同,而這裡我們不考慮訪問性的問題,所以下面的 都以struct來演示。struct foo 初始化列表 ...
C 初始化列表
與其他函式不同,建構函式除了有名字,引數列表和函式體之外,還可以有初始化列表,初始化列表以冒號開頭,後跟一系列以逗號分隔的初始化字段。struct foo 初始化列表 建構函式的執行可以分成兩個階段,初始化階段和計算階段,初始化階段先於計算階段。所有類型別 class type 的成員都會在初始化階...