從彙編看c 初始化列表初始化成員變數

2022-05-15 09:41:56 字數 2339 閱讀 9194

簡略來說,編譯器會對初始化列表按照成員變數的宣告順序重新一一排序,安插到建構函式中進行初始化操作,而且這些初始化操作在建構函式裡面使用者自己定義的任何**之前。

下面是c++原始碼:

class

x };

intmain()

下面是main函式裡面的彙編碼:

;

13 : int main()

xoreax, eax

movesp, ebp

popebp

ret0

_main endp

下面是建構函式的彙編碼:

??0x@@qae@xz proc                    ;

x::x, comdat

;_this$ = ecx

;8 : x() : j(1), i(2), l(3)

moveax, dword ptr _this$[ebp]

movesp, ebp

popebp

ret0

??0x@@qae@xz endp

從彙編嗎可以看到,在初始化列表中,雖然j排在i的前面(i的宣告在j前),但是,編譯器插入到建構函式裡面的初始化操作仍然將i的初始化排在了j的前面。並且編譯器插入到建構函式裡面的初始化操作都在建構函式裡面原有初始化操作(初始化k)的前面,儘管l的宣告順序比k的宣告順序晚。

如果不注意宣告順序和初始化列表順序的這種關係,可能會導致下面的問題:

class

x };

intmain()

通過上面的分析可以知道,i先初始化,但這時候初始化i的時候j還沒初值,所以i的值無法預知。

有4中情況必須使用初始化列表:

1 當初始化乙個引用成員時

2 當初始化乙個const成員時

3 當呼叫基類的建構函式,而它擁有引數時

4 當呼叫成員變數的建構函式,而它擁有引數時

下面來看一種情形:

先來看c++原始碼:

class

x x() {}

};class

y };

intmain()

接下來是main函式中的彙編碼:

_main    proc

;21 : int main()

xoreax, eax

movesp, ebp

popebp

ret0

_main endp

下面主要來看物件y的建構函式彙編碼:

??0y@@qae@xz proc                    ;

y::y, comdat

;_this$ = ecx

;15 : y()

moveax, dword ptr _this$[ebp]

movesp, ebp

popebp

ret0

??0y@@qae@xz endp

可以看到,在物件y的建構函式裡面,在執行物件y的建構函式裡面任何賦值操作之前,首先呼叫了成員物件x的預設建構函式,接下來產生了乙個臨時物件,然後將臨時物件在拷貝給成員物件x。這裡可以看到,初始化成員物件x的操作是呼叫預設建構函式來完成的,物件y的建構函式裡面的賦值操作只是乙個拷貝過程。

下面將成員物件的初始化放到初始化列表中,並且去掉其預設建構函式

先看c++原始碼

class

x };

class

y };

intmain()

下面看main函式彙編碼:

_main    proc

;20 : int main()

xoreax, eax

movesp, ebp

popebp

ret0

_main endp

下面主要看物件y的建構函式彙編碼:

??0y@@qae@xz proc                    ;

y::y, comdat

;_this$ = ecx

;15 : y() : x(2)

moveax, dword ptr _this$[ebp]

movesp, ebp

popebp

ret0

??0y@@qae@xz endp

可以看到,和上面的最大不同是,即使類x沒有預設建構函式,編譯器也沒有報錯,並且,初始化成員物件的操作由有引數的建構函式完成,當中並沒有產生臨時物件,效率高。

C 初始化成員列表

c 在類的建構函式中,可以兩種方式初始化成員資料 data member 1,在建構函式的實現中,初始類的成員資料。諸如 class point int getx int gety 2,還可以定義初始化成員列表 initializer list 來初始化成員資料 data member 改寫建構函式...

C 成員初始化列表

類物件的構造順序是這樣的 1.分配記憶體,呼叫建構函式時,隱式 顯示的初始化各資料成員 初始化階段可以是顯式的或隱式的,取決於是否存在成員初始化表。隱式初始化階段按照宣告的順序依次呼叫所有基類的預設建構函式,然後是所有成員類物件的預設建構函式。2.進入建構函式後在建構函式中執行一般計算 計算階段由建...

C 成員初始化列表

c 初始化類的成員,不僅可以用constructor完成,也可以用初始化類成員列表來完成。有些情況只能用第一種,而且通常第一種效率高些。兩者區別 1,普通變數編譯器會預設替你初始化。它們既能初始化,也能被賦值,而常量const按照其意思只能被初始化,不能賦值。所有const member只能用成員初...