class ClassObject {
public:
ClassObject();
virtual ~ClassObject();
private:
int x;
};
int ClassObject::x=10;
コンパイルに失敗するのはなぜですか? 静的メンバーをこのように初期化できるのであれば、非静的メンバーも初期化できるはずだと思います。
class ClassObject {
public:
ClassObject();
virtual ~ClassObject();
private:
int x;
};
int ClassObject::x=10;
コンパイルに失敗するのはなぜですか? 静的メンバーをこのように初期化できるのであれば、非静的メンバーも初期化できるはずだと思います。
静的メンバーは特別です。クラスが定義されるとすぐに、メモリが割り当てられます。そのクラスのオブジェクトをいくつ作成しても、それらのオブジェクトはすべて同じメモリを参照します。
これは、非静的メンバーには当てはまりません。その特定のクラスのオブジェクトを作成しない限り、非静的メンバーにはメモリが割り当てられないため、上記の方法でそれらをインスタンス化しようとすると、コンパイラ エラーが発生します。
x
newの初期化に使用される値を宣言することを意味しているとClassObject
思います。つまり、それは
ClassObject() : x(10) { }
構文の問題は、コンパイラがすべての ClassObject コンストラクターでその初期化を行うためのコードを生成する必要があることです。int ClassObject::x = 10;
つまり、すべてのコンストラクターを定義するコンパイル単位、およびコンストラクターを暗黙的に生成するコンパイル単位で初期化が利用可能な場合にのみ機能します。そして、それを保証する唯一の方法は、値がクラス定義の外側ではなく、クラス定義の内側に設定されている場合です。(ただし、これは C++11 で可能になりました - tacp のコメントのリンクを参照してください。)
構文を機能させたい場合は、宣言された値を非表示の static としてどこかに格納し、コンストラクターがそれを取得して の初期値として使用することを認識できるようにする必要がありますx
。ただし、この static は存在する場合と存在しない場合があり、別のコンパイル単位のコンストラクターについて知ることができる唯一のポイントはリンク時です。したがって、この非表示の static が存在する場合 (または冗長データ) から x を初期化する余分な冗長コードを生成するか、これを解決するためにリンク時のコード生成を義務付けます。これは、コンパイラ開発者に大きな負担をかけます。はい、可能ですが、これが許可されていない場合は、全体的に簡単です。