C 學習 類初始化列表的分析總結

2022-09-16 02:36:11 字數 3194 閱讀 1595

出處:

1.在子類構造時完成父類(沒有預設建構函式)的初始化引數傳入:

#include 

class

foo

};

class

bar :

public

foo

};

int

main()

2.初始化const成員和reference成員

#include 

using

namespace

std;

class

const_field

intgeti()

intgetref()

private

:

const

int_constant;

int&ref;

inti;

};

int

main()

注:初始化列表在建構函式函式體執行之前完成,在建構函式函式體執行中,資料成員的設定是賦值,而不是初始化。初始化階段可以是顯式或隱式的,這要取決於類成員的型別,對於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 

using

namespace

std;

class

bar

bar(

const

bar &bar)

private

:

intx;

};

bar::bar()

bar::bar(

intx) : x(x)

class

foo

;

foo::foo(bar bar)

//foo::foo(bar bar):bar(bar){}

int

main()

出處:

C 初始化列表學習

何謂初始化列表 與其他函式不同,建構函式除了有名字,引數列表和函式體之外,還可以有初始化列表,初始化列表以冒號開頭,後跟一系列以逗號分隔的初始化字段。在c 中,struct和class的唯一區別是預設的克訪問性不同,而這裡我們不考慮訪問性的問題,所以下面的 都以struct來演示。複製 如下 str...

類初始化列表

以前在寫 時用初始化列表,因為前輩們說效率更高,也沒有去想為什麼。最近看 item4 確保物件在使用前被初始化,恍然大悟。如果使用賦值的方式在建構函式中初始化 類成員變數 會先呼叫這個 類成員變數 類的預設建構函式,再呼叫賦值函式。而使用初始化列表初始化 類成員變數 只會呼叫這個 類成員變數 類的拷...

類初始化列表

初始化類的成員有兩種方式,一是使用初始化列表,二是在建構函式體內進行賦值操作。使用初始化列表主要是基於效能問題,對於內建型別,如int,float等,使用初始化類表和在建構函式體內初始化差別不是很大,但是對於類型別來說,最好使用初始化列表,為什麼呢?由上面的測試可知,使用初始化列表少了一次呼叫預設建...