2012-10-09 27 views
0
#include <iostream> 
using namespace std; 
class Ex { 
private: 
    int i; 
    float f; 
public: 
    Ex(int i,float f):i(i),f(f) { 
     cout << this->i << '\t' << this->f << endl; 
    } 
    ~Ex(){ 
     cout << "destructor"; 
    } 
}; 
int main() { 
    Ex i(10,20.1f); 
} 

在程序上面我寫了上面,如果構造就像參數的構造函數如下:初始化列表,局部變量VS數據成員

Ex(int i,float f){ 
     i=i; 
     f=f; 
     cout << this->i << '\t' << this->f << endl; 
    } 

這裏對象的數據成員初始化爲垃圾因爲數據成員由於同名的局部變量而被隱藏。 但是,在上面的程序中,它沒有明確這一點工作正常。如何?

回答

2

之前已經詢問過類似的問題,例如, herehere,但許多答案指出這是(與Konstantin D - Infragistics所說的不同),而不是編譯器特定的,我找不到任何實際引用標準相關部分的答案。

所以他們在這裏。我重點突出重點陳述。

(§12.6.2/ 10)在非委託構造函數,以下列順序進行初始化:

- 首先,只對最派生類的構造函數(1.8) ,虛擬基類按照它們出現在基類的有向無環圖的深度優先從左到右遍歷的順序進行初始化,其中「從左到右」是基類的出現順序派生類的基類說明符列表。
- 然後,直接基類以聲明順序初始化,因爲它們出現在base-specifier-list中(不管mem-initializers的順序如何)。
- 然後,非靜態數據成員按照它們在類定義中聲明的順序進行初始化(不管mem-initializers的順序如何)。
- 最後,執行構造函數體的複合語句。

(§12.6.2/ 12)mem-initializer的表達式列表或加載初始化列表中的名稱是,在構造函數的範圍內進行了評估,其中指定了mem初始值設定項。 [實施例:

class X { 
     int a; 
     int b; 
     int i; 
     int j; 
    public: 
     const int& r; 
     X(int i): r(a), b(i), i(i), j(this->i) { } 
    }; 

初始化X::rX::a,用構造參數i的值初始化X::b初始化X::i用構造參數i的值,並初始化X::jX::i值;每次創建類X的對象時都會發生這種情況。 - 結束示例]
[注意:由於mem初始值設定項是在構造函數的範圍內進行求值的,因此this指針可用於mem初始值設定項的表達式列表中以引用正在初始化的對象。 - 注意]

0

編譯器的設計與左手if爲類範圍內的成員和右手if作爲構造函數範圍的成員合作。

+0

這不是編譯器實現的細節。它是C++標準所要求的。 – jogojapan

+0

@jogojapan謝謝,我糾正了我的帖子。 –

1

由於以下點,其中所有的C++編譯器遵循的規則:

  1. 構造初始化列表只能使用類構造
  2. 在初始化列表僅在同一類中的成員和基類 構造存在可以稱爲
  3. 初始化中相同的順序發生的類數據成員 被聲明

當編譯器將if看作是初始化器列表的一部分時,它立即標識爲類成員,並且事情進行得很順利(點編號。 2)。
如果您嘗試使用除if以外的任何其他值,編譯器將會報錯。

在第二種情況下,你做了任務,編譯器有兩個候選人if。它可以是類成員或局部變量。由於局部變量處於最內層,編譯器認爲ii而不是this->i