Foo(int num): bar(num)
このコンストラクトは、C++ ではメンバー初期化リストと呼ばれます。
簡単に言うと、メンバーを値に初期化します。bar
num
コンストラクタ内の初期化と代入の違いは何ですか?
メンバーの初期化:
Foo(int num): bar(num) {};
メンバーの割り当て:
Foo(int num)
{
bar = num;
}
メンバー初期化子リストを使用してメンバーを初期化することと、コンストラクター本体内で値を割り当てることには大きな違いがあります。
メンバー初期化子リストを介してフィールドを初期化すると、コンストラクターが 1 回呼び出され、オブジェクトが 1 回の操作で構築および初期化されます。
代入を使用すると、フィールドは最初にデフォルトのコンストラクターで初期化され、次に (代入演算子を介して) 実際の値で再割り当てされます。
ご覧のとおり、後者には作成と割り当ての追加のオーバーヘッドがあり、ユーザー定義のクラスではかなりの量になる可能性があります。
Cost of Member Initialization = Object Construction
Cost of Member Assignment = Object Construction + Assignment
後者は実際には次と同等です。
Foo(int num) : bar() {bar = num;}
前者は次のものと同等ですが、
Foo(int num): bar(num){}
組み込み (コード例) または POD クラス メンバーの場合、実質的なオーバーヘッドはありません。
いつメンバー初期化リストを使用する必要がありますか?
次の場合は、メンバー初期化子リストを使用する必要があります (むしろ強制されます) 。
- あなたのクラスには参照メンバーがあります
- クラスに静的でない const メンバーがあるか、
- クラス メンバーにデフォルトのコンストラクターがないか、
- 基本クラスのメンバーの初期化または
- コンストラクターのパラメーター名がデータ メンバーと同じ場合 (これは必須ではありません)
コード例:
class MyClass {
public:
// Reference member, has to be Initialized in Member Initializer List
int &i;
int b;
// Non static const member, must be Initialized in Member Initializer List
const int k;
// Constructor’s parameter name b is same as class data member
// Other way is to use this->b to refer to data member
MyClass(int a, int b, int c) : i(a), b(b), k(c) {
// Without Member Initializer
// this->b = b;
}
};
class MyClass2 : public MyClass {
public:
int p;
int q;
MyClass2(int x, int y, int z, int l, int m) : MyClass(x, y, z), p(l), q(m) {}
};
int main() {
int x = 10;
int y = 20;
int z = 30;
MyClass obj(x, y, z);
int l = 40;
int m = 50;
MyClass2 obj2(x, y, z, l, m);
return 0;
}
MyClass2
デフォルトのコンストラクターがないため、メンバー初期化リストを使用して初期化する必要があります。
- 基本クラス
MyClass
にはデフォルトのコンストラクターがないため、そのメンバーを初期化するには、メンバー初期化リストを使用する必要があります。
メンバー初期化子リストを使用する際の注意事項:
クラス メンバー変数は、クラスで宣言された順序で常に初期化されます。
これらは、メンバー初期化子リストで指定された順序では初期化されません。
つまり、メンバー初期化リストは初期化の順序を決定しません。
上記を考えると、クラス定義で宣言されている順序と同じ順序でメンバーの初期化を維持することを常にお勧めします。これは、2 つの順序が異なる場合にコンパイラが警告しないためですが、比較的新しいユーザーは、初期化の順序としてメンバ Initializer リストを混同し、それに依存するコードを記述する可能性があります。