2012-04-25 15 views
4

コンストラクタで初期化リストを使用すべきではない場合や、それをどのように譲渡で克服することができる場合、誰かがサンプルコードを引用してもらえますか?コンストラクタで初期化リストを使用しないのはいつですか?

私は以下の文

あなたのクラスが異なる順序でthisオブジェクトのデータメンバを初期化する必要がある2つのコンストラクタを持っているとき、これは起こるかもしれないために例を探しています。または、2人のデータメンバーが自己参照型である場合に発生する可能性があります。または、データメンバがこのオブジェクトへの参照を必要としているときに、コンストラクタの本体を開始する{(特定のコンパイラがその特定の警告を発行したときに){また、変数を使用する前に変数(パラメータ、グローバルなど)に対してif/throwテストを実行して、このメンバの1つを初期化する必要があるとき。私はあなたの文の著者が参照していることをメインコンセプトは、初期化リスト内の変数への呼び出しは、が順番にあなたが初期化リストでそれらを参照してください、しかしではない起こるという事実であると考えてい

+2

初期設定の順序はオプションではありません。初期設定ステートメントを書く順番に関係なく同じです。 –

+1

あなた自身の質問に対する回答をリストし、サンプルを求めているようですか?どうして?あなたは何を理解していないのですか? –

+0

質問を編集してその声明の著者を追加できますか?言い換えれば、どこからその声明を取ったのですか? – nbro

答えて

2

は、いくつかの例は以下のとおりです。


クラスが に必要な2つのコンストラクタは異なる順序で、このオブジェクトのデータメンバを初期化していたときにこれが発生する可能性があります。この例では

class Example1 { 
public: 
    Example1(std::string decoded, std::string encoded) 
     : decoded_(decoded), 
     encoded_(encoded) {} 
    explicit Example1(std::string encoded) 
     : decoded_(), // Can't use "decoded_(Decode())" since "encoded_" isn't initialised 
     encoded_(encoded) { 
    decoded_ = Decode(); // Assign here instead of initialising 
    } 
private: 
    std::string Decode(); // decodes class member "encoded_" 
    std::string decoded_, encoded_; 
}; 

それは、彼らが我々が初期化リストで自分の順番を入れ替えた場合でも、クラスで宣言された順番だから、decoded_は常にencoded_前に初期化されます。


場合、またはデータ・メンバーは、このオブジェクトへの参照を必要とし、あなたが前 にこのキーワードの使用方法についてのコンパイラの警告を避けたい {それは(コンストラクタの体を開始しますあなたの特定の コンパイラがその特定の警告を発行したとき)。ここで

class Example2 { 
public: 
    Example2() : functor_() { 
    functor_ = std::bind(&Example2::Do, this); 
    } 
private: 
    void Do(); 
    std::function<void()> functor_; 
}; 

functor_は、それが割り当てられて/初期化されるときthisを使用する必要があります。初期化リストにfunctor_を初期化する場合、thisポインタは、その時点で完全に初期化されていないオブジェクトを参照することになります。それは特定の状況に応じて安全ですが、絶対確実なオプションは、コンストラクタ本体の内部まで設定functor_を延期することです。thisは完全に初期化されたオブジェクトを参照します。


それとも、以前ご このメンバーの1を初期化するために、その変数を使用している場合/変数のテストを投げる(パラメータ、 グローバルなど)を行う必要があります。

class Example3 { 
public: 
    Example3(int force, int acceleration) 
     : force_(force), 
     acceleration_(acceleration), 
     mass_(0) { 
    if (acceleration_ == 0) 
     throw std::exception("Can't divide by 0"); 
    mass_ = force_/acceleration_; 
    } 
private: 
    int force_, acceleration_, mass_; 
}; 

うまくいけば、これは自明です。


私は、2人のデータメンバーが自己参照

ので、私は、私は怖いそのために例を与えることはできませんされたときに

が何を意味するかわかりません。

+0

@Fraser ....素晴らしい説明!!! –

+0

このステートメントへの参照を追加してください。 "この例では、decoded_はencoded_の前に常に初期化されます。これは、初期化リストで順序を入れ替えたとしても、そのクラスで宣言された順序です。 – nbro

4

変数はクラス定義にリストされています。あなたは初期化リストを使用する2つの異なるコンストラクタを持っている場合

  • が、彼らは同じ順序でそれらを初期化しなければならないことを意味

  • シーケンシングの上にコントロール(あなたが持っている場合は重要であるかもしれませんmutually-従属メンバ)は限定されています

Scott MeyerのEffective C++を参照することをお勧めします。多くの他の多くの有用な情報veトピック)。ここで

+0

また、組み込み型でない限り、初期化リストを使用しない場合でも同じ順序で初期化されます。 –

関連する問題