32

メンバーの宣言時にメンバーを初期化できない理由があるのではないかと思います。

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

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

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

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

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

4

3 に答える 3

28

非静的メンバーの初期化は、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)であるかメンバー関数宣言(のようにT)であるかがあいまいです。

追加された機能を使用すると、この括弧構文でメンバーを初期化できないため、これは問題になりません。次のような中括弧または等しい初期化子を使用する必要があります。

int i = x;
int i{x};

これらはデータメンバーにしかなれませんので、もう問題はありません。

非静的メンバー初期化子を提案するときに考慮しなければならなかった問題の詳細については、提案N2628を参照してください。

于 2013-03-16T16:59:17.310 に答える
5

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

この点でいくつかの進化がありました。すでに、C ++ 98の標準化の最後に、委員会は、整数型の静的constメンバーに対してこれを行う可能性を追加しました---主に、コンパイラが初期化を確認できる必要があるコンテキストでこれらを使用できるためです。C ++ 11では、宣言で初期化子を指定できるように言語が拡張されましたが、これは単なる省略形であり、実際の初期化はコンストラクターの先頭で行われます。

于 2013-03-16T16:55:14.083 に答える
-2

2つ以上のオブジェクト(クラスのインスタンス)が宣言されると、それらのオブジェクトはこれらのデータメンバーを共有します。したがって、値はコンストラクターを使用して初期化できます。そのため、宣言中にクラスメンバーを初期化することはできません。

于 2018-12-28T06:21:21.067 に答える