非const静的メンバーのクラス内初期化を禁止します



Forbids Class Initialization Non Const Static Member



からの転送: 非const静的メンバーのクラス内初期化を禁止します
今日プログラムを書いたとき、新しいエラーが発生しました。そうですね、プログラムを組むたびに、新しい問題に遭遇することがあると感じています。治る日を楽しみにしています、はは。事故コードは次のとおりです。

class Employee { public: Employee() {myid = id++} Employee(const std::string &n) {myid = id++name = n} int get_id() {return myid} const std::string get_name() {return name} private: std::string name static int id int myid }

コンパイル後:
画像
本の中の具体的な指示の場所を覚えていません。 Baiduで確認したところ、stackoverflowにそのような投稿があったことがありました。答えはとてもプロフェッショナルだと思います。翻訳して記録します。元の意味を維持し、静的、一定、積分は翻訳されません、私は誰もが理解していると信じています:




Q:クラスの静的メンバーを初期化できないのはなぜですか?

採用された回答:C ++標準では、静的定数の整数データまたは列挙データのみをクラス内で初期化できます。
参照:C ++ 039.4.2静的データメンバー



§4静的データメンバーがconst整数型またはconst列挙型である場合、クラス定義でのその宣言は、整数定数式(5.19)でなければならない定数初期化子を指定できます。その場合、メンバーは積分定数式で表示できます。メンバーがプログラムで使用され、名前空間スコープ定義に初期化子が含まれていない場合でも、メンバーは名前空間スコープで定義されます。

静的データメンバーが定数整数型または定数型である場合、そのクラスの宣言に定義部分が含まれていると、定義部分は積分定数式である必要があります。この場合、メンバーは整数定数式で表示できます。このメンバーをプログラムで使用する場合は、その名前空間のドメインスコープを明確にし、初期化子を含めないでください。

整数型とは?



bool char wchar_tには、signedまたはunsignedによって変更されたケースが含まれます。総称して整数型と呼ばれ(この文はC ++の基本型であり、文字列や配列とは区別されます)、整数型の同義語は整数型です。

脚注:
したがって、列挙型は整数ではありませんが、列挙型はint、unsigned int、long、unsignedlongに変換できます。
作業領域(これは元のテキストでの記述方法であり、おそらくコードルーチンの領域です):
列挙型トリックを使用して、クラス内配列を初期化できます。

class A { static const int a = 3 enum { arrsize = 2 } static const int c[arrsize] = { 1, 2 } }

標準でこの動作が許可されていないのはなぜですか?
Bjarneは説明しました:

クラスはヘッダーファイルで具体的に定義され、ヘッダーファイルは多くの変換単位に含まれます。ただし、リンクルールが複雑になりすぎないようにするために、C ++ではオブジェクトごとに特定の定義が必要です。 C ++でメモリに格納されているオブジェクトのクラス内定義が許可されている場合、このルールは破られます。

なぜ静的なだけなのか
const整数型と列挙型はクラス内初期化を許可しましたか?
静的const整数型と列挙型のみがクラス内で初期化できるのはなぜですか?
答えはBjarneによるその段落にあります。 'C ++では、すべてのオブジェクトに特定の定義が必要です。 C ++でメモリに格納されているオブジェクトをクラス内で定義できる場合、このルールは破られます。

静的const整数のみがコンパイル時定数として扱われることに注意してください。コンパイラーは、このような整数の変更がどのような状況でも変更されないことを理解しているため、コンパイラーは特定の最適化と改善を行うことができます。コンパイラはそのような変数を単にインライン化するので、それらはもはやメモリに格納されません。メモリに保持されている要件が削除されたため、Bjaneが言ったルールの例外になりました。

static const integerなどの変数がクラス内初期化の使用を許可されている場合でも、そのような変数のアドレスを取得することは許可されていないことに注意してください。変数は、クラス外の定義がある場合にのみアドレス指定できます。