出處:
1.在子類構造時完成父類(沒有預設建構函式)的初始化引數傳入:
#include
classfoo
};
classbar :
public
foo
};
intmain()
2.初始化const成員和reference成員
#include
usingnamespace
std;
classconst_field
intgeti()
intgetref()
private
:
const
int_constant;
int&ref;
inti;
};
intmain()
注:初始化列表在建構函式函式體執行之前完成,在建構函式函式體執行中,資料成員的設定是賦值,而不是初始化。初始化階段可以是顯式或隱式的,這要取決於類成員的型別,對於built-in成員其實都一樣,但是對於類成員,是否存在成員初始化表則有所不同:若不存在則是隱式初始化,按照宣告的順序依次呼叫所有類成員函式所屬基類的預設建構函式(見後邊的練習),在函式體內有賦值動作呼叫賦值建構函式。若存在則屬於顯式初始化,類成員使用複製建構函式完成初始化,這也就是我們有時會說在初始化列表中初始化開銷會小些的原因(因為若在函式體內再賦值,那麼類成員函式的預設建構函式執行所做的工作都是無用功),例如:
account()
這裡面的string型的_name在賦值前已經被初始化階段隱式初始為空串(呼叫了string的預設建構函式),所以在函式體中的賦值是完全沒有意義的。
總之,建議使用初始化列表(注意是按照成員宣告順序,而不是列表順序)來做物件建立時初始化工作。
初始化順序為:
基類 成員資料成員(初始化列表)
建構函式函式體
附:練習
#include
using namespace std;
class test
test(const test & r)
test & operator= (const test& r)
private:
static int ctor_count;//only a declaration
};
int test::ctor_count=0;// definition + initialization
class task
};
int main(void)
執行結果:
[root@localhost ~]# ./a.out
ctor 1
ctor 2
assignment op 3
解釋:static int是為了更好的說明問題,不要被這個型別所迷惑。第一行表示程式在構造t。第二行表示預設初始化時呼叫預設建構函式,第三行是構造task時的賦值。
將程式的初始化修改:
task (int num, const test & n):pid(num),name(n) {}
執行結果是:
ctor 1
copy ctor 2
下邊的這個程式也可以說明問題,如果還不理解上例的話:
#include
usingnamespace
std;
classbar
bar(const
bar &bar)
private:
intx;
};
bar::bar()
bar::bar(intx) : x(x)
classfoo
;
foo::foo(bar bar)
//foo::foo(bar bar):bar(bar){}
intmain()
出處:
C 初始化列表學習
何謂初始化列表 與其他函式不同,建構函式除了有名字,引數列表和函式體之外,還可以有初始化列表,初始化列表以冒號開頭,後跟一系列以逗號分隔的初始化字段。在c 中,struct和class的唯一區別是預設的克訪問性不同,而這裡我們不考慮訪問性的問題,所以下面的 都以struct來演示。複製 如下 str...
類初始化列表
以前在寫 時用初始化列表,因為前輩們說效率更高,也沒有去想為什麼。最近看 item4 確保物件在使用前被初始化,恍然大悟。如果使用賦值的方式在建構函式中初始化 類成員變數 會先呼叫這個 類成員變數 類的預設建構函式,再呼叫賦值函式。而使用初始化列表初始化 類成員變數 只會呼叫這個 類成員變數 類的拷...
類初始化列表
初始化類的成員有兩種方式,一是使用初始化列表,二是在建構函式體內進行賦值操作。使用初始化列表主要是基於效能問題,對於內建型別,如int,float等,使用初始化類表和在建構函式體內初始化差別不是很大,但是對於類型別來說,最好使用初始化列表,為什麼呢?由上面的測試可知,使用初始化列表少了一次呼叫預設建...