我的问题源于学习 Effective C++通过斯科特迈耶斯。 在那本书的第二条中,写了以下内容:
To limit the scope of a constant to a class, you must make it a member and, to ensure there's at most one copy of the constant, you must make it a static member.
写的很对。然后立即给出以下示例:
class GamePlayer {
private:
static const int NumTurns = 5;
int scores[NumTurns];
....
};
那么下面就是上面例子的写法:
What you see above is a declaration and not a definition of NumTurns.
我的第一个问题是:这句话是什么意思?
紧接着提到以下内容:
Usually C++ requires that you provide a definition for anything you use, but class specific constants that are static and of integral type (e.g - integers, chars, bools) are an exception. As long as you don't take their address, you can declare them and use them without providing a definition. If you do take the address of a class constant, or if your compiler incorrectly insists on a definition even if you don't take the address, you provide a separate definition like this :
const int GamePlayer::Numturns; //definition of NumTurns
为什么现在是定义而不是声明?
我理解函数上下文中的差异,但不理解常规变量上下文中的差异。另外,有人可以通过
来扩展作者的意思吗... if you do take the address of a class constant, or if your .. part of the above quoted paragraph ?
P.S : 我是 C++ 的新手。
最佳答案
就像函数一样,变量可以有“纯声明性”声明和实际定义。你很困惑,因为你之前可能没有遇到过很多纯变量声明。
int i; // Definition
extern int i, j; // (Re)declares i, and declares j
extern int j = 0; // Defines j (confusing, eh?)
正如您习惯使用函数一样,定义就是声明,但并非所有声明都是定义。 §3.1/2 阅读
A declaration is a definition unless […] it declares a static data member in a class definition (9.2, 9.4),
因此,类内静态数据成员声明永远不会定义它们声明的变量。但是,有时不必存在变量定义。 当您可以直接使用它的值而不需要变量运行时存在时就是这种情况。
在技术术语中,只要静态数据成员(或任何实体,就此而言)不是“使用过的”,就不必定义它。 §3.2/3 中定义了所有实体的Odr 使用:
A variable
x
whose name appears as a potentially-evaluated expressionex
is odr-used byex
unless applying the lvalue-to-rvalue conversion (4.1) tox
yields a constant expression (5.20) that does not invoke any non-trivial functions and, ifx
is an object,ex
is an element of the set of potential results of an expressione
, where either the lvalue-to-rvalue conversion (4.1) is applied toe
, ore
is a discarded-value expression (Clause 5).
这看起来很复杂,在标准的早期版本中它更简单。但是,它粗略地说,当某个表达式“立即”访问变量值时,该变量不会被某个表达式使用,并且这种访问会产生一个常量表达式。 Meyers 的“获取其地址”示例只是众多用于 odr 的示例之一。
对于某个类A
及其静态数据成员i
,
class A {
static const int i = 57; // Declaration, not definition
};
const int A::i; // Definition in namespace scope. Not required per se.
关于c++ - C++中变量的声明和定义有什么区别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29954191/