web-dev-qa-db-ja.com

C ++:コンストラクターで変数を初期化する場所

可能性のある複製:
C++初期化リスト

オプション1とオプション2で変数を初期化することの長所と短所は何ですか?

class MyClass
{
public:
    MyClass( float f, char a );
private:
    float mFloat;
    char mCharacter;
    bool mBoolean;
    int mInteger;
};

MyClass::MyClass( float f, char a ) : mFloat( f ), mBoolean( true ) // option 1.
{
    // option 2
    mCharacter = a;
    mInteger = 0;
}

編集:なぜオプション2がそんなに一般的ですか?

81
user542687

つまり、可能な場合は常に初期化リストを優先します。 2つの理由:

  • クラスの初期化リストで変数に言及しない場合、コンストラクターはデフォルトで初期化してから、作成したコンストラクターの本体を入力します。これは、オプション2により、各変数が2回書き込まれることを意味します。1回はデフォルトの初期化用、もう1回はコンストラクター本体の割り当て用です。

  • また、他の回答でmwigdahlとavadaが述べたように、constメンバーと参照メンバーはonlyを初期化リストで初期化できます。

また、変数は常に、初期化リストにリストされている順序ではなく、クラス宣言で宣言された順序で初期化されることに注意してください(適切な警告が有効になっていると、コンパイラーはリストの順序が間違っていると警告を表示します)。同様に、デストラクタは、クラスのデストラクタのコードが実行された後、クラス宣言の最後から最初に、逆の順序でメンバーデストラクタを呼び出します。

106
Greg Howell

この特定の例には適用されませんが、オプション1を使用すると、参照型(または以下に示すconst型)のメンバー変数を初期化できます。オプション2はサポートしていません。一般的に、オプション1はより強力なアプローチです。

21
mwigdahl

コンストラクタが「初期化リスト」または「割り当て」を使用する必要がありますか? を参照してください

簡単に言うと、特定のケースでは、何も変わりません。しかし:

  • コンストラクターを持つクラス/構造体メンバーの場合、オプション1を使用する方が効率的です。
  • オプション1でのみ、参照メンバーを初期化できます。
  • オプション1のみでconstメンバーを初期化できます
  • オプション1のみ、コンストラクターを使用して基本クラスを初期化できます
  • オプション2のみが、コンストラクターを持たない配列または構造体を初期化できます。

オプション2がより一般的である理由についての私の推測は、オプション1があまり知られていないということです。オプション2の構文は、新しいC++プログラマにとってより自然に感じます。

10

オプション1では、メンバー変数を明示的に初期化するために正確に指定された場所を使用できます。

3
Diego Sevilla

他にも多くの理由があります。可能であれば、初期化リスト内のすべてのメンバー変数を常に初期化する必要があります。

http://www.parashift.com/c++-faq-lite/ctors.html#faq-10.6

2
Salgar

オプション1では、constメンバーを初期化できます。これはオプション2で行うことはできません(割り当てられているため、初期化されていません)。

constメンバーは、本体ではなくコンストラクター初期化子で初期化する必要があるのはなぜですか?

1
Avada Kedavra