初期化リストです。デフォルトで構築してからコンストラクターの本体に割り当てるのではなく、割り当てたい値を使用してメンバー変数を直接構築できます。
A
デフォルトのコンストラクターと 1 つの引数を受け入れるコンストラクターを持つクラスがあるとします。
struct A
{
A() : n(0) { } // For scalar types, n = 0 in the constructor's body is equivalent
A(int n) : n(a) { } // Should be marked as "explicit", but not relevant here
int a;
};
X
そして、 type のメンバー変数を持つクラスA
。のコンストラクターは、の variableに割り当てる必要がX
ある型の引数を取ります。初期化リストがない場合は、次のようにします。int
A
a
struct X
{
X(int n) { a.a = n; } // First invoke A::A(), then assign n to a.a
A a;
};
しかし、ここでは 1 つではなく2 つのa
命令があります。メンバー変数の (潜在的に高価な) デフォルトの構築と、その後に必要に応じてその状態を変更するための代入です。構築する必要がある引数が既にわかっている場合、a
その初期化をオーバーライドするためだけにデフォルトの構築を最初に実行することは意味がありません。
ただし、スカラー型を初期化する場合(例の場合のように)、初期化リストに基づく形式は、コンストラクターの本体の通常の割り当てに基づく形式と同等です。スカラー型はゼロで初期化されていないためです。デフォルトで (より正確には、どのような方法でも初期化されません)。
関連情報として、初期化リストでは、コンストラクターの引数の名前は、構築するメンバー変数の名前を隠しません。
struct X
{
X(int a) : a(a) { } // OK (although I do not like it)
int a;
};
反対に、通常の代入でa
は、代入の両側でコンストラクターの引数と見なされます。
struct X
{
X(int a) { a = a; } // Self-assignment of the constructor's argument...
int a;
};
とはいえ、メンバー変数と関数の引数に同じ名前を使用することは良い習慣だとは思いません。他の人が書いたコードを読む必要がある場合は、これを知っておくとよいので、これについて言及しました。