クラスのコンストラクターでメンバーのコンストラクターを呼び出すことはできますか?
クラスbar
にクラスタイプfoo
のメンバーMClass
があるとしましょう。 MClassのコンストラクターでbarのコンストラクターを呼び出すことはできますか?そうでない場合、どうすればメンバーバーを初期化できますか?
これは、構成(集約)でのメンバーの初期化の問題です。
はい、もちろんできます!それがコンストラクタ初期化リストの目的です。これは、デフォルトのコンストラクターを持たないメンバー、定数、参照を初期化するために必要な重要な機能です。
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) { }
// ^^^^^^^^^^^^^^^^^^^
};
さらに、派生クラスコンストラクターで基本クラスのデフォルト以外のコンストラクターを指定するには、初期化子リストが必要です。
はい、できます:
#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
このような:
class C {
int m;
public:
C(int i):
m(i + 1) {}
};
メンバーコンストラクターがパラメーターを必要とする場合は、それらを渡すことができます。これらは、クラスコンストラクターパラメーターおよび既に初期化された型から作成された式にすることができます。
Remember:メンバーは、初期化リストに表示される順序ではなく、クラスで宣言された順序で初期化されます。
基本クラスにdefaultコンストラクタがない場合は、イニシャライザリストを使用します。
struct foo{
foo( int num )
{}
};
struct bar : foo {
bar( int x ) : foo(x)
// ^^^^^^ initializer list
{}
};
はい、できます。これは、クラスの初期化リストで行われます。例えば:
class MClass
{
foo bar;
public:
MClass(): bar(bar_constructor_arguments) {};
}
これにより、渡された引数を使用してbar
が構築されます。通常、引数は、クラスの他のメンバーまたはコンストラクターに渡された引数になります。この構文は、引数のないコンストラクターを持たないメンバーには必須です。