1

だから私がクラスを持っているなら

class Transaction {

int no;
char dollar;

public:

    Transaction();
    ~Transaction();
}

そして私のコンストラクタ/デストラクタで

Transaction::Transaction {
    cout << "Entering constructor" << endl;
}

Transaction::~Transaction {
    cout << "Leaving program" << endl;
}

そのコードは、コンストラクタとデストラクタが機能するのに十分ですか?コンストラクターで何も宣言していなくても、クラスのデータメンバーを安全な状態に設定しますか?

4

3 に答える 3

5

サブオブジェクトの初期化子を指定せずにコンストラクターを指定すると、各サブオブジェクトはデフォルトで初期化されます。

規格のセクション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();
}
于 2013-03-01T02:30:37.787 に答える
1

クラスには単純なデータメンバーしかないため、デストラクタは必要ありません(または必要ありません)。

ただし、コンストラクターでデータメンバーを初期化する必要があります。

Transaction::Transaction()
  : no(0), dollar('$') {
    cout << "Entering constructor" << endl;
}

そうしないと、初期化されず、ランダムな値が含まれる可能性があります(C ++は、コンストラクターで初期化しない場合、プリミティブな非静的メンバーの特定の値への初期化を保証しません)。ポインタメンバーがある場合、これは特に陰湿になる可能性があります。

于 2013-03-01T02:22:20.847 に答える
0

いいえ、コードは必要ありません。実際、ほとんどの言語では、それを省略でき、クラスが適切に構築されます。

于 2013-03-01T02:19:39.773 に答える