在Effective C++(第 3 版)第 2 项(Preferconst
和to )中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
根据这本书(也是我自己的话),定义中没有给出任何值,因为它已经在声明中给出了。
这让我认为我已经知道声明和定义的定义令人困惑(在问这个问题之前我在谷歌上仔细检查过):
- 为什么
static const int NumTurns = 5
没有定义?不是在这里NumTurns
初始化为一个值5
,是不是声明和定义一起出现的时候才叫初始化? - 为什么
static
整数常量不需要定义? - 当没有定义值时,为什么第二个代码片段被认为是定义,但包含该值的类内部的声明仍然不是一个(基本上回到我的第一个问题)?
- 初始化不是定义吗?为什么这里没有违反“唯一一个定义”的规则?
可能我现在只是在这里混淆了自己,所以有人可以从头开始重新教育我:为什么这两行代码声明和定义而不是另一行,那里有任何初始化实例?初始化也是一个定义吗?
信用:代码片段直接从书中引用。
编辑:附加参考定义和声明之间有什么区别?
- 声明引入了标识符和类型
- 定义实例化和实现
所以,是的......这似乎不是这里发生的事情。
编辑 2:我认为编译器可能会优化静态整数常量,方法是不将其存储在内存中,而只是在代码中内联替换它。但是如果NumTurns
使用地址,为什么声明没有自动变为声明+定义,因为实例化已经存在?
编辑3:(此编辑与原始问题的关系不大,但仍然很突出。我把它放在这里,这样我就不需要复制粘贴到下面每个答案的评论中。请回答我这个在评论中。谢谢!)
感谢您的回答。现在我的头脑更清晰了,但编辑 2 的最后一个问题仍然存在:如果编译器在程序中检测到需要定义的条件(例如&NumTurns
,在程序中使用),为什么它不自动重新解释static const int NumTurns = 5;
为声明和定义而不是仅声明?它具有程序中其他任何地方的定义所具有的所有语法。
我来自学校的Java背景,并且不需要以上述方式为静态成员进行单独的定义。我知道 C++ 是不同的,但我想知道为什么上面是这样的。如果地址从不使用,则静态整数成员被内联替换,这对我来说更像是一种优化而不是基本功能,所以为什么我需要解决它(在条件不存在时提供单独的语句作为定义即使原始语句的语法足够了)而不是相反(编译器将原始语句视为定义,因为语法足够,所以需要有一个定义)?