7

デフォルトのコンストラクターのないクラスA、タイプAのオブジェクトを返すファクトリメソッドfactoryA、およびメンバーとしてAを持つクラスBがあるとします。この場合、BのタイプAのメンバーは、Bのコンストラクター初期化リストで初期化する必要があることを私は知っています。理由は私には完全には明らかではないので、誰かが私にそれを説明できればそれは素晴らしいことです。また、Aのコンストラクターへのパラメーターを、Bのコンストラクター内で計算する必要がある場合、たとえば、データベースまたはその性質のものにクエリを実行する必要がある場合はどうなりますか?Aにデフォルトのコンストラクターを提供せずに以下のセットアップを使用する方法はありますか?前もって感謝します。

class A {
private:
  int _i;
public:
  A(int i) : _i(i) {} 
};

A factoryA(bool b) {
  if(b)
    return A(1);
  else return A(2);
}

class B {
private:
  A _a;
public:
  B(int j) {
    if(j > 0)
      _a = factoryA(true);
    else _a = factoryA(false);
  }
};
4

3 に答える 3

9

メンバー オブジェクトは、コンストラクターの本体 (中括弧の間の部分) に入る前に常に初期化されます。初期化子リストにメンバーを指定しない場合、デフォルトで構築されます。だからそれを言及してください!

B::B(int j) : _a(factoryA(0 < j)) { };

これはfactoryA、引数値が 0 より大きい場合、またはそれ以外のtrue場合に関数を呼び出し、その呼び出しによって返された値でメンバーを初期化します。jfalse_a

于 2012-09-08T12:49:53.053 に答える
6

その理由は私には完全には明らかではないので、誰かが私にそれを説明できればそれは素晴らしいことです.

クラス [*] の場合、この_a = factoryA(true);行は を呼び出します_a.operator=(factoryA(true))。でメンバー関数を呼び出すには、既に初期化されている_a必要があります。_aしたがって、コンパイル時のエラーでなければ、有効ではありません。

また、A のコンストラクターへのパラメーターを B のコンストラクター内で計算する必要がある場合、たとえば、データベースまたはその性質の何かにクエリを実行することによって、どうすればよいでしょうか? A にデフォルトのコンストラクターを提供せずに、以下のセットアップを使用する方法はありますか?

コピーまたは移動コンストラクターがある限りA、関数の戻り値で初期化でき、その関数は、A提供された引数に応じて異なるコンストラクターを使用しても、必要なことを何でも実行できます。

class B {
private:
  A _a;
  static A getA(int i);
public:
  B(int j) : _a(getA(j)) {
  }
};

A B::getA(int j)
{
  if (j > 0)
    return factoryA(true);
  else
    return factoryA(false);
}

[*] 例外もあります。

于 2012-09-08T06:41:26.817 に答える
0

この場合、A へのポインター、つまり A* _a を使用してから、必要な場所で A コンストラクターを呼び出すことをお勧めします。

于 2012-09-08T05:03:02.637 に答える