web-dev-qa-db-ja.com

コンストラクターでクラスメンバーのコンストラクターを呼び出す

クラスのコンストラクターでメンバーのコンストラクターを呼び出すことはできますか?

クラスbarにクラスタイプfooのメンバーMClassがあるとしましょう。 MClassのコンストラクターでbarのコンストラクターを呼び出すことはできますか?そうでない場合、どうすればメンバーバーを初期化できますか?

これは、構成(集約)でのメンバーの初期化の問題です。

24
shampa

はい、もちろんできます!それがコンストラクタ初期化リストの目的です。これは、デフォルトのコンストラクターを持たないメンバー、定数、参照を初期化するために必要な重要な機能です。

class Foo
{
  Bar x;     // requires Bar::Bar(char) constructor
  const int n;
  double & q;
public:
  Foo(double & a, char b) : x(b), n(42), q(a) { }
  //                      ^^^^^^^^^^^^^^^^^^^
};

さらに、派生クラスコンストラクターで基本クラスのデフォルト以外のコンストラクターを指定するには、初期化子リストが必要です。

37
Kerrek SB

はい、できます:

#include <iostream>

using std::cout;
using std::endl;

class A{
public:
    A(){
        cout << "parameterless" << endl;
    }

    A(const char *str){
        cout << "Parameter is " << str <<endl;
    }
};

class B{
    A _argless;
    A _withArg;

public:
    // note that you need not call argument-less constructor explicitly.
    B(): _withArg("42"){
    }
};

int main(){
    B b;

    return 0;
}

出力は次のとおりです。

parameterless
Parameter is 42

ideone.comでこれを表示

6
elder_george

このような:

class C {
  int m;

public:

  C(int i):
    m(i + 1) {}

};

メンバーコンストラクターがパラメーターを必要とする場合は、それらを渡すことができます。これらは、クラスコンストラクターパラメーターおよび既に初期化された型から作成された式にすることができます。

Remember:メンバーは、初期化リストに表示される順序ではなく、クラスで宣言された順序で初期化されます。

3
phs

基本クラスにdefaultコンストラクタがない場合は、イニシャライザリストを使用します。

struct foo{
   foo( int num )
   {}
};

struct bar : foo {
   bar( int x ) : foo(x)
               // ^^^^^^ initializer list
   {}
};
3
Mahesh

はい、できます。これは、クラスの初期化リストで行われます。例えば:

class MClass 
{

  foo bar;

public:

  MClass(): bar(bar_constructor_arguments) {};
}

これにより、渡された引数を使用してbarが構築されます。通常、引数は、クラスの他のメンバーまたはコンストラクターに渡された引数になります。この構文は、引数のないコンストラクターを持たないメンバーには必須です。

2
Dave S