クラス定義で他の静的データメンバーを初期化できないのはなぜですか? これが禁止された特定の理由はありましたか?
静的データ メンバーは、多くの点で (特にコンパイラの観点から)、外部リンケージを持つ名前空間スコープのデータ オブジェクトに似ています。
静的データ メンバーの宣言は単なる宣言であり、定義ではありません。これは、グローバル オブジェクトの宣言に似ておりextern
、オブジェクトを使用できる翻訳単位に含める必要があります。
定義は正確に 1 つの翻訳単位に出現する必要があり、これは初期化式が属する場所です。式が定数式の厳密な基準を満たさない限り、その値はそれが呼び出された時間とコンテキストに大きく依存する可能性があります。このような初期化子式が複数の翻訳単位で発生すると、実行コンテキストと初期化の時間、そして最終的に初期値があいまいになります。
クラス スコープのコンパイル時定数は、特定の種類の定数静的メンバーの例外を作成するのに十分価値があると見なされました (列挙型の初期化や配列の次元の指定などに使用できます)。定数式を使用すると、異なる翻訳単位で異なる初期化子の値を誤って発生させることは、少なくともより困難です。constexpr
この概念は、メンバーを使用して C++11 で拡張されました。
データ メンバーがクラスに固有である場合、それらのクラスに関連するスコープではなく、グローバル名前空間スコープで宣言されているのはなぜですか?
宣言はクラス スコープ内にあります。非定義宣言は文字どおりクラス定義内にあり、クラス メンバーの他のクラス外定義と同様に、定義は名前空間スコープに表示されます。メンバー名はクラス名で修飾されているため、クラスのメンバーとして明確に示され、初期化式は実際にはクラスのスコープ内にあると見なされます (少なくとも C++11 では、私は C+ を持っていません)。 +98/03 標準はこちらから入手できます)。