4

コンストラクターで初期化リストを使用するべきではない場合、誰かがサンプルコードを引用できますか?それを代入でどのように克服できますか?

以下のステートメントの例を探しています

thisこれは、オブジェクトのデータメンバーを異なる順序で初期化する必要がある2つのコンストラクターがクラスにある場合に発生する可能性があります。または、2つのデータメンバーが自己参照である場合に発生する可能性があります。または、データメンバーがthisオブジェクトへの参照を必要とし、コンストラクターの本体を開始する{の前にthisキーワードを使用することについてのコンパイラー警告を回避したい場合(特定のコンパイラーがその特定の警告を発行した場合)。または、変数を使用してこのメ​​ンバーの1つを初期化する前に、変数(パラメーター、グローバルなど)に対してif/throwテストを実行する必要がある場合。

4

2 に答える 2

4

あなたのステートメントの作者が言及していた主な概念は、初期化リストの変数への呼び出しが、初期化リストに表示される順序ではなく、変数がクラスにリストされている順序で発生するという事実だと思います。定義

つまり、

  • 初期化リストを使用する2つの異なるコンストラクターがある場合、それらは同じ順序で初期化する必要があります
  • 順序付けの制御(相互に依存するメンバーがある場合は重要になる可能性があります)は制限されています

これをカバーしているScottMeyerを見てみることをお勧めしますEffective C++(他の多くの有用で有益なトピックの中で)。

于 2012-04-25T21:07:21.377 に答える
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_


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

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

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


または、変数を使用してこのメ​​ンバーの1つを初期化する前に、変数(パラメーター、グローバルなど)に対してif/throwテストを実行する必要がある場合。

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つのデータメンバーが自己参照の場合

ですから、その例をあげることはできません。

于 2012-04-25T22:32:00.803 に答える