2013-03-16 18 views
19

宣言時にメンバーを初期化できない理由があるのだろうかと思います。宣言でクラスメンバーを初期化できないのはなぜですか?

class Foo 
{ 
    int Bar = 42; // this is invalid 
}; 

コンストラクタ初期化リストを使用するのと同等です。

class Foo 
{ 
    int Bar; 
public: 
    Foo() : Bar(42) {} 
} 

私の個人的な理解は、上記の例がはるかに表現力豊かで意図的であるということです。さらに、これは短い構文です。私は他の言語要素との混乱の可能性を見ません。

これについての公式な説明はありますか?

+20

C++ 11では使用できます。 – chris

+0

私のコンパイラは私に言った:* "エラー:データメンバ初期化子は許可されていません" *。 – danijar

+2

あなたのコンパイラは(すべての)C++ 11をまだサポートしていません。 –

答えて

18

非静的メンバーの初期化は、C++ 11より前のこのように行うことはできませんでした。 C++ 11コンパイラでコンパイルする場合は、与えられたコードをうれしく受け入れる必要があります。

私は、最初にそれを許さないのは、データメンバ宣言が定義ではないからです。導入されるオブジェクトはありません。 int x;などのデータメンバーがある場合は、実際にクラスの種類のオブジェクトを作成するまで、intオブジェクトは作成されません。したがって、このメンバ上のイニシャライザは誤解を招きます。メンバーの初期化リストの対象となるのは、メンバーに値を割り当てることができるのは建設中だけです。

静的でないメンバーの初期化を追加する前に、アイロンをかける技術的な問題もありました。次の例を考える:

struct S { 
    int i(x); 
    // ... 
    static int x; 
}; 

struct T { 
    int i(x); 
    // ... 
    typedef int x; 
}; 

これらの構造体は、部材iを解析する時、解析されている場合、のように(Sのように)データメンバ宣言またはメンバ関数宣言(あるかどうか曖昧ですin T)。

追加された機能を使用すると、このparantheses構文でメンバーを初期化できないため、これは問題にはなりません。これらは、データのみのメンバーになることができますので、我々はこれ以上何の問題もない

int i = x; 
int i{x}; 

:あなたのようなブレース・オア・イコール初期化子を使用する必要があります。

非スタティックメンバーイニシャライザを提案するときに考慮しなければならない問題を詳しく徹底的に見てみると、提案書N2628を参照してください。

+0

'i'が解析されているときに' x'が不明なので、単純にコンパイルエラーにならないはずですか?伝統的にフォワード宣言は、このような問題を解決するために使用されました。 – doc

4

主な理由は、初期化がオブジェクトに適用されるか、または インスタンスに適用され、クラス内の宣言ではオブジェクトまたはインスタンスが ではありません。あなたはそれを構築するまで を開始するまでそれを持っていません。

この点についてはいくつかの進化があります。すでに のC++ 98の標準化が終了した時点で、委員会は タイプの静的constメンバーのために の可能性を追加しました---主に、 コンパイラが可能でなければならないコンテキストで使用できるためです初期化を確認します。 C++ 11では、 という言語が拡張され、 にイニシャライザを指定することができましたが、これはちょっと簡略化されて—です。実際は の初期化がコンストラクタの最上部で行われます。

+2

データメンバーの初期化も、宣言の順番で行われます。 –

+0

@CaptainObvliousそうだけど、Jamesが何を意味したのかは、ctor initリストの実行中に常に初期化が行われたということだと思います。 ctor decl/definitionに関連するメンバー宣言の位置によって影響を受けます。 –

関連する問題