c++ - C++中变量的声明和定义有什么区别?

标签 c++

我的问题源于学习 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 expression ex is odr-used by ex unless applying the lvalue-to-rvalue conversion (4.1) to x yields a constant expression (5.20) that does not invoke any non-trivial functions and, if x is an object, ex is an element of the set of potential results of an expression e, where either the lvalue-to-rvalue conversion (4.1) is applied to e, or e 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/

相关文章:

c++ - 如何获得 clang-format 将大括号初始化结构的参数放在同一行?

c++ get方法不返回指向节点的指针

c++ - 使用独立于模板的 enable_if 时,模板类的模板化友元函数出现链接器错误

c++ - 临时字符串的内存分配

c++ - fwrite, fread - fread 的问题

c++ - 循环遍历结果集

c++ - Linux 上的互锁等效项

c++ - 这个 shared_ptr 是如何自动转换为原始指针的?

c++ - priority_queue 常量表达式

c++ - 在 C++ 中将 MapB 同步到 MapA