類成員的初始化是有順序的,不注意是要有大問題的。看下面的例子:
class C
{
public:
int a;
int b;
public:
C():b(1),a(b)
{ }
};
C c;
printf("%d, %d",c.a,c.b);
那么c.a等于1嗎?
結果實際上是沒有定義。
看一下編譯器(VC2008)的匯編代碼:
00901A83 mov eax,dword ptr [this]
00901A86 mov ecx,dword ptr [this]
00901A89 mov edx,dword ptr [ecx+4]
00901A8C mov dword ptr [eax],edx
00901A8E mov eax,dword ptr [this]
00901A91 mov dword ptr [eax+4],1
可以看到賦1給b的是在最后一部,而a的賦值卻在前(見0901A89),這個時候b的值[ecx+4]是沒有定義的。
那為什么這樣?
這是因為C++標準規定成員初始化順序是按照聲明的順序決定,因此最后編譯幫我們聲明了上面的代碼。
如果一定要先給b賦值,怎么辦?
可以這么做:
C():b(1)
{
a = b;
}
再來看反匯編代碼:
00A01A80 mov dword ptr [ebp-8],ecx
00A01A83 mov eax,dword ptr [this]
00A01A86 mov dword ptr [eax+4],1
a = b;
00A01A8D mov eax,dword ptr [this]
00A01A90 mov ecx,dword ptr [this]
00A01A93 mov edx,dword ptr [ecx+4]
00A01A96 mov dword ptr [eax],edx
這里可以看到b先被賦值,而a由于不在成員初始化列表中,所以放在隨后被賦值。