C++ const 数据存储位置

看如下代码:

class GamePlayer {
    private:
        static const int NumTurns = 5; // 常量声明式
        int scores[NumTurns];          // 使用该常量
        ...
}

然而你所看到的是 NumTurns 的声明式而非定义式。通常 C++ 要求你对你所使用的任何东西提供一个定义式, 但如果它是一个 class 专属常量又是 static 且为整数类型(intergral type,例如 ints,chars,bools),则需特殊处理。只要不取他们的地址, 你可以声明并使用它们而无须提供定义式。但如果你取某个 class 专属常量的地址,或纵使你不取其地址而你的编译器却(不正确地)坚持要看到一个定义式, 你就必须另外提供定义式如下:

const int GamePlayer::NumTurns; // NumTurns 的定义;
                                // 下面告诉你为什么给予数值

请把这个式子放进一个实现文件而非头文件。由于 class 常量已在声明时获得初值,因此定义时不可以再设初值。

以上所有来自《Effective C++》第三版 P14


我不理解的是 不取其地址的时候,可以访问 NumTurns ? ,于是我代码进行验证:

#include <iostream>
class GamePlayer {
public:
    static const int NumTurns = 5; // 常量声明式
};
const int GamePlayer::NumTurns;
int main()
{
    std::cout &lt;&lt; GamePlayer::NumTurns &lt;&lt; std::endl;
    // 如果没有加上 const int GamePlayer::NumTurns; 对 NumTurns 进行定义,下面这样语句会报错:
    //   undefined reference to `GamePlayer::NumTurns
    std::cout &lt;&lt; &amp;(GamePlayer::NumTurns) &lt;&lt; std::endl;
    return 0;
}

代码的验证结果和书中说的是一致的。那么问题就来了,NumTurns 没有定义的时候可以访问,却无地址,那它存储在什么地方呢?

于是我猜测,难道未定义时,编译器会把它当成宏来处理?只是进行了符号替换操作(我指的是狭义的工作方式,并不是指在预处理时候进行的替换), 要不然怎么会没有地址呢?我网上查的时候看到一个CSDN的帖子内容挺好的。我将感觉能解释的通的几个点罗列了一下:


2013.03.11 补充:

对于本文中的内容,可以用"常量折叠"来解释,我找了些资料,大家可以看一下:

First created: 2013-03-07 00:00:00
Last updated: 2022-12-11 Sun 12:49
Power by Emacs 27.1 (Org mode 9.4.4)