サブオブジェクトの初期化子を指定せずにコンストラクターを指定すると、各サブオブジェクトはデフォルトで初期化されます。
規格のセクション8.5は、次のことを規定しています。
オブジェクトに初期化子が指定されていない場合、オブジェクトはデフォルトで初期化されます。初期化が実行されない場合、自動または動的な保管期間を持つオブジェクトの値は不確定です。[注:静的またはスレッドの保存期間を持つオブジェクトはゼロで初期化されます。3.6.2を参照してください。—エンドノート]
そしてそれ
デフォルトの場合-タイプのオブジェクトを初期化するということは、次のことをT
意味します。
- が
T
(おそらくcv修飾された)クラス型の場合、のデフォルトコンストラクターT
が呼び出されます(Tにアクセス可能なデフォルトコンストラクターがない場合、初期化は不正な形式になります)。
- Tが配列型の場合、各要素はデフォルトで初期化されます。
- それ以外の場合、初期化は実行されません。
プログラムがconst修飾型のオブジェクトのデフォルトの初期化を要求する場合、は、ユーザーが提供するデフォルトのコンストラクターを持つクラス型T
でなければなりません。T
サブオブジェクトを初期化するには、 ctor-initializer-listと、メンバー宣言のbrace-or-equal-initializerの2つの方法があります(非静的メンバーの場合、後者はC ++ 11で新しく追加されました)。
実際には、これは、初期化子を指定しない場合、int
およびなどのプリミティブ型の変数はchar
、以前にメモリに残っていた値を保持することを意味します。ほとんどの場合、どのような値になるかを予測することは非常に困難ですが、パスワードなどの機密性の高いデータが残っている可能性があることに注意する必要があります。
静的ストレージ期間の変数(名前空間スコープのオブジェクトとそのメンバーなど)の初期化の場合、標準はさらに次のことを提供します(同じセクション)。
静的ストレージ期間のすべてのオブジェクトは、他の初期化が行われる前に、プログラムの起動時にゼロで初期化されます。
これは、コンストラクターを定義しなかった場合の値の初期化中に発生することとは微妙に異なります。
タイプのオブジェクトを値初期化するということは、次のことをT
意味します。
- が
T
(おそらくcv修飾された)クラス型であり、ユーザー提供のコンストラクターがある場合、Tのデフォルトコンストラクターが呼び出されます(Tにアクセス可能なデフォルトコンストラクターがない場合、初期化は不正な形式になります)。
- が
T
(おそらくcv修飾された)非ユニオンクラスタイプであり、ユーザー提供のコンストラクターがない場合、オブジェクトはゼロで初期化され、T
暗黙的に宣言されたデフォルトコンストラクターが自明でない場合、そのコンストラクターが呼び出されます。
- が配列型の場合
T
、各要素は値で初期化されます。
- それ以外の場合、オブジェクトはゼロで初期化されます。
ただし、効果は同じです。プリミティブメンバーはゼロに設定され、他のすべてのメンバーでは引数ゼロのコンストラクターが呼び出されます。
静的ストレージ期間の変数に対してのみゼロ初期化を行うと、バグを見つけるのが困難になることが多いため、すべてのメンバーを明示的に初期化するというnneonneoのアドバイスは適切です。しかし、ブレースまたはイコールイニシャライザーの手法を使用することは完全に実行可能です。
class Transaction
{
int no = 0;
char dollar = 0;
public:
Transaction();
~Transaction();
}