17

一部のPOD変数はデフォルトで初期化されますが、そうでないものもあります。(PODタイプにはint、、、floatポインター、共用体、PODタイプの配列、PODタイプの構造体などが含まれます。)

スコープとストレージクラスは、PODタイプのデフォルトの初期化にどのように影響しますか?

具体的には、次のうちどれが暗黙的に初期化されますか。

  • 自動ストレージを備えたローカル変数
  • 静的ローカル変数
  • 静的グローバル変数
  • 外部変数
  • で割り当てられた変数new
  • クラスのPODメンバー(コンストラクターでの明示的な初期化なし)

これらの状況のいくつかに関連する既存の質問があることは知っていますが、包括的ではありません(特定の状況にのみ対処します)。

4

2 に答える 2

21

自動保存期間のあるローカル変数は自動的に初期化されていません。初期化されていない変数を使用すると未定義の動作が発生するため、冗長な場合でも変数を明示的に初期化することをお勧めします。

ゼロ初期化されているPODタイプについて、C++03標準3.6.2非ローカルオブジェクトの初期化は次のように述べています。

§1静的ストレージ期間(3.7.1)のオブジェクトは、他の初期化が行われる前にゼロ初期化(8.5)されるものとします。ゼロ初期化と定数式による初期化は、まとめて静的初期化と呼ばれます。他のすべての初期化は動的初期化です。定数式(5.19)で初期化された静的ストレージ期間を持つPODタイプ(3.9)のオブジェクトは、動的初期化が行われる前に初期化される必要があります。

したがって、静的ストレージ期間(スコープが何であれ)を持つPODタイプは、ゼロで初期化されることが標準で保証されています。

クラスのPODメンバー(コンストラクターでの明示的な初期化なし)

この状況は、12.6.2ベースとメンバーの初期化で説明されており、次のように記述されています(選択されたパーツ)。

特定の非静的データメンバーまたは基本クラスがmem-initializer-idによって指定されていない場合(コンストラクターにctor-initializerがないためにmem-initializer-listがない場合を含む)、次のようになります。

—エンティティが非静的データメンバーであり、エンティティクラスが非PODクラスである場合、エンティティはデフォルトで初期化されます(8.5)。

それ以外の場合、エンティティは初期化されません

クラスXのコンストラクターの呼び出しが完了した後、Xのメンバーがコンストラクターのmem-initializersで指定されておらず、default-initializedでもvalue-initializedでも、コンストラクターの本体の実行中に値が指定されていない場合、メンバーの値は不確定です。

例:

class C
{
public:
    C(int x, int z) : x(x), z(z) { }
    int x, y, z;
};

int main(void)
{
    C* c = new C(1,3);
    std::cout << c->y; // value of y is undetermined !!!
}
于 2013-03-04T22:33:09.333 に答える
11

PODについてのみ話している場合は、ローカルおよびグローバルの静的変数と外部変数のみを話します。これらはどこかで定義する必要があるためです。

で割り当てられたPODnew時々初期化されます-初期化を明示的にすると:

int* x = new int();

それを指すようにint初期化されたを作成しますが、0x

int* x = new int;

初期化されていないをx指すようになりintます。

場合によっては-PODクラスメンバー-明示的に初期化できます(コンストラクターに含まれていなくても):

struct X
{
   int x;
};

X x;        //x.x is not initialized
X y = X();  //y.x is 0
于 2013-03-04T22:27:31.540 に答える