Effective C++ (第3 版)、項目 2 (Preferおよびto )const
では、クラス固有の定数のコード セグメントは次のように読み取られます。enum
inline
#define
class GamePlayer {
private:
static const int NumTurns = 5; // constant declaration
int scores[NumTurns]; // use of constant
...
};
この本は、(私自身の言葉で) それstatic const int NumTurns = 5;
は、アドレスが決して使用されない静的な整数定数でない限り、クラス メンバーに対して C++ で通常必要とされる定義ではないと述べています。上記が定数に当てはまらない場合、またはコンパイラが何らかの理由で定義を要求する場合は、次のように定義を実装ファイルで提供する必要があります。
const int GamePlayer::NumTurns; // definition of NumTurns; see
// below for why no value is given
この本によると (私自身の言葉でも)、値は宣言で既に指定されているため、定義には値が指定されていません。
これは、宣言と定義の定義について私がすでに知っていると思っていたことを混乱させています (そして、この質問をする前に Google で再確認しました):
static const int NumTurns = 5
定義がないのはなぜですか?NumTurns
ここの値に初期化されていませ5
んし、宣言と定義が一緒になった場合を初期化というのではないでしょうか。- なぜ
static
整数定数は定義を必要としないのですか? - 値が定義されていない場合、2 番目のコード スニペットが定義と見なされるのはなぜですか?
- 初期化は定義ではありませんか?ここで「唯一の定義」ルールに違反しないのはなぜですか?
この時点で私は自分自身を混乱させている可能性があるので、誰かが親切に私をゼロから再教育できますか: なぜこれらの 2 行のコード宣言と定義が他の行ではなく、初期化のインスタンスがあるのですか? 初期化も定義ですか?
クレジット: コード スニペットは本から直接引用されています。
- 宣言は、識別子と型を導入します
- 定義はインスタンス化して実装します
だから、ええ...それはここで起こっていることではないようです.
編集 2 : コンパイラが静的整数定数をメモリ内に格納せず、コード内でインラインに置き換えるだけで最適化できる可能性があると考えています。しかし、NumTurns
アドレスが使用されている場合、インスタンス化が既に存在するため、宣言が宣言 + 定義に自動的に変更されないのはなぜですか?
編集3:(この編集は元の質問とはあまり関係がありませんが、まだ未解決です。以下の各回答のコメントにコピーして貼り付ける必要がないように、ここに配置します。これについて回答してくださいコメントで. ありがとう!)
答えてくれてありがとう。私の頭は今でははるかに明確になりましたが、編集 2 からの最後の質問はまだ残っています: コンパイラが定義が必要なプログラム内の条件を検出した場合 (たとえば、プログラムで使用されている場合)、なぜ自動的に再解釈し&NumTurns
ないのですか?static const int NumTurns = 5;
宣言のみではなく宣言と定義?プログラム内の他の場所の定義が持つすべての構文があります。
私は学校で Java のバックグラウンドを持っており、上記の方法で静的メンバーに対してこのような個別の定義を作成する必要はありませんでした。C++が違うのはわかっているのですが、上記がどうしてこうなるのか知りたいです。アドレスが使用されていない場合にインラインで置換される静的な整数メンバーは、基本的な機能というよりも最適化のように聞こえますが、なぜそれを回避する必要があるのですか (条件が使用されていない場合に定義として別のステートメントを提供する)元のステートメントの構文で十分であるにもかかわらず満たされる) 逆の方法ではなく (構文が十分であるため、必要なときに元のステートメントを定義として扱うコンパイラー)?