デフォルトメンバー初期化子(クラスメンバーのデフォルト初期化子)は、C++11で導入された構文で、クラスのメンバー変数の宣言時にデフォルト値を直接指定することを可能にします。この機能は、データの他の初期化方法と混同されることがよくあります。
初期のC++では、メンバーは宣言時に初期化することができず、値はコンストラクタの本文または初期化リスト内でのみ設定されました。デフォルトメンバー初期化子の導入(C++11)は、可読性を向上させ、不定初期化の誤りのリスクを低下させました。
フィールドが明示的に初期化されていない場合、それらは「ゴミ」(未定義)値を持ちます。コンストラクタ内の代入は初期化リストに比べて効果的ではなく、デフォルトメンバー初期化子を無視すると、クラスの拡張や新しいコンストラクタの作成が複雑になります。
単純な値にはデフォルトメンバー初期化子を使用し、複雑な場合(特に依存するまたは非標準の値が必要な場合)には、コンストラクタの初期化リストを使用します。
コード例:
class Widget { int x = 42; // デフォルトメンバー初期化子 std::string name = "default"; // デフォルトメンバー初期化子 public: Widget() = default; // x=42, name="default" Widget(int xx) : x(xx), name("new") {}// x=xx, name="new" };
主な特徴:
メンバーがコンストラクタの本文内で初期化される場合、デフォルトメンバー初期化子は適用されますか?
答え:
いいえ。初期化リストで指定されていない場合、変数は最初にデフォルト値(デフォルトメンバー初期化子)で初期化され、その後コンストラクタの本文で代入され、効果が低くなります。
継承時のデフォルトメンバー初期化子を持つクラスのメンバーの初期化順序はどうなりますか?
答え:
最初に基底クラスのメンバーが初期化され、次に派生クラスのメンバーが初期化されます。各メンバーについて、デフォルトメンバー初期化子が指定されている場合は初期化リストが最初に使用され、それ以外の場合はデフォルトメンバー初期化子が使用され、初期化されない(PODの場合)ことになります。「二重初期化」は発生しません。
デフォルトメンバー初期化子は、クラスのstaticメンバーに適用できますか?
答え:
いいえ、staticメンバーはデフォルトメンバー初期化子を通じて初期化できません。これらはクラスの外部で初期化する必要があるか、C++17のインラインstaticを使用する必要があります。
例:
struct S { static int a = 5; // エラー! };
動的文字列を持つクラスがいくつかのコンストラクタで初期化を忘れた場合。後でアクセスすると未定義動作になります。
利点:
欠点:
すべてのフィールドがデフォルトメンバー初期化子を持っています。追加のコンストラクタは必要に応じて初期化リストを通じて必要なメンバーを明示的に初期化します。
利点:
欠点: