2013-05-04 22 views
10

staticメンバーは、これらの例外を除き、クラス本体で初期化されなくてもよい。const一体型でクラスの静的データメンバの初期化C++で

  • staticメンバーはの
  • staticメンバーであることができますconstexprリテラルタイプ

でなければならない、あなたは、なぜこれらの元説明することができます何か?

また、これが成立する

const staticデータメンバーがメンバーは、通常、クラス定義の外で定義されるべきであること、クラス本体で初期化されている場合でも。

これは決してわかりません。この余分な定義のポイントは何ですか?

ここでいくつかの直感を取得しようとしています。

+2

重要な点は、変数をodr-usedにするかどうかです。そうでないかぎり、変数を参照するたびに*値*を貼り付けるだけで十分であるため、実際に変数を定義する必要はありません。 –

+3

これは**余分な**定義ではありません。それは定義です。クラス本体の内部に**宣言**があります。 –

+1

異なる翻訳単位(= cppファイル)から静的データメンバーにアクセスしたい場合は、すべての翻訳単位が参照する場所、つまり静的メンバーが定義されている単一の翻訳単位を定義する必要があります。これは、(グローバル)extern変数と同じことです。 – dyp

答えて

6

なぜクラス定義に初期化子がありますか? constconstexpr静的データメンバのための2つの例外に関する

[class.static.data]/3

は[注:これらの両方の場合において、メンバーは、定数式で表示されること。 - 終了ノート]

I.e.初期化子を使用して、定数式で使用することができます。

struct s 
{ 
    static std::size_t const len = 10; 
    int arr[len]; 
}; 
std::size_t const s::len; 

lenは、クラス定義で初期化されていない場合は、コンパイラが簡単にarrの長さを定義するために次の行にその値を知ることができませんでした。

一つは、クラス定義で、const非非constexpr静的データメンバのための初期化子を許可について議論ができ、これは、初期化順序を妨げる可能性:

[basic.start.init]/2

明示的に特殊化されたクラステンプレートの静的データメンバーの定義は、順序付けられた初期化を持っています。他のクラステンプレート静的データメンバー(すなわち、暗黙的にまたは明示的にインスタンス化された特殊化)は、順序付けされていない初期化を有する。 静的記憶期間を持つ他の非ローカル変数は、順序付けられた初期化を持っています。

つまり、イニシャライザを含む定義の順序が重要です。非ローカルオブジェクトの(動的な)初期化の順序は、翻訳単位内でのみ定義されます。これは、非const、非constexpr静的データメンバーの初期化子を含む定義がなければならないもう一つの理由です。


この追加定義のポイントは何ですか。

これは既にIMOのコメントで回答されています。 ODRを追加することもできます。つまり、外部リンケージを持つ名前として、静的データメンバーは(ODRを使用している場合は)1つの翻訳単位で定義する必要があります。この翻訳単位を選択するのはプログラマの責任です。

関連する問題