類數據成員的初始化,這份工作主要是構造函數負責的,構造函數的職責之一就是對數據成員進行正確初始化。實際上,構造函數的執行過程主要有兩個階段:
(1)初始化階段
(2)普通計算階段
初始化階段是指對數據成員的初始化主要在構造函數的初始化列表中進行。普通計算階段是指對數據成員的初始化是在構造函數的函數體中進行。因此,初始化階段與普通計算階段是兩個不同的概念,需要予以區分。下面來看看什麼是構造函數的初始化列表。
下面是一個時鐘類Clock的定義:
class Clock { public: Clock(int hour=0, int minute=0, int second = 0); ~Clock(){} private: int hour_; int minute_; int second_; };下面是Clock的構造函數實現:
Clock::Clock(int hour, int minute, int second): hour_(hour), minute_(minute), second_(second) { /* //這此稱為普通計算段 hour_ = hour; minute_ = minute; second_ = second; */ cout << "Clock()..."<上面代碼中的“:”號後面的代碼就是構造函數的初始化列表,也就是構造函數執行的第一階段,利用構造函數的初始化列表來對數據成員的初始化其效率是更高的,其實在函數體內執行的代碼在某種意義上來說,不能稱為初始化,是賦值操作,是構造函數的普通計算段,它的效率更低。構造函數的初始化列表中,如果有多個數據成員,成員之間則以逗號分隔。
我們這裡說的數據成員,包含普通數據類型的數據成員,如int,double, char等,還有類對象的數據成員,const數據成員以及引用數據成員。對數據成員的初始化我們建議在構造函數的初始化列表中。而對於下面幾種情形而言是必須要在構造函數的初始化列表中進行的:
(1) 類對象成員,當它所對應的類沒有默認構造函數時,只能在構造函數的初始化列表中進行(如果有默認構造函數,雖然可以不在初始化列表中進行,考慮到效率的問題,不建議在普通計算段中初始化)
(2) const成員,其初始化也只能在構造函數的初始化列表中進行
(3) 引用成員, 其初始化也只能在構造函數的初始化列表中進行
聲明一下:數據成員的初始化順序,與構造函數的初始化列表中的順序無關,與在類中聲明的成員順序有關。
下面是示例:
class Object { public: enum E_TYPE { TYPE_A = 100, TYPE_B }; public: Object(int num = 0): num_(num), kNum_(num), refNum(num_) //主要關注這行初始化列表。 { cout << "Object..."<
這裡需要指出的是,對於const成員,不同的對象有不同的const值,obj1的kNum為100,obj2的kNum為200,如果想讓所有對象均有一個共同的常量值,不能用const,而應該使用枚舉型,如上述代碼中的TYPE_A, TYPE_B;