为什么需要明确定义静态变量?

sha*_*ats 25 c++ static

在课堂里:

class foo
{
public:
    static int bar; //declaration of static data member
};

int foo::bar = 0; //definition of data member
Run Code Online (Sandbox Code Playgroud)

我们必须明确定义静态变量,否则会产生一个

undefined reference to 'foo::bar'

我的问题是:

为什么我们必须给出静态变量的明确定义?


请注意,这与先前提出的问题重复undefined reference to static variable.这个问题打算问一下静态变量的明确定义背后的原因.

AnT*_*AnT 23

从C++语言开始,就像C一样,建立在独立翻译的原则之上.每个翻译单元由编译器独立编译,不需要任何其他翻译单元的知识.整个程序后来才会在连接阶段汇集在一起​​.链接阶段是链接器看到整个程序的最早阶段(它被视为编译器正确编写的目标文件的集合).

为了支持这种独立翻译原则,每个具有外部联系的实体必须在一个翻译单元中定义,并且只在一个翻译单元中定义.用户负责在不同的翻译单元之间分发这些实体.它被认为是用户意图的一部分,即用户应该决定哪个翻译单元(和目标文件)将包含每个定义.

这同样适用于类的静态成员.该类的静态成员是具有外部链接的实体.编译器希望您在某个翻译单元中定义该实体.此功能的全部目的是让您有机会选择该翻译单元.编译器无法为您选择它.这又是你意图的一部分,你必须告诉编译器.

这不再像过去那样重要,因为该语言现在设计用于处理(并消除)大量相同的定义(模板,内联函数等),但单一定义规则仍然存在根植于独立翻译的原则.

除了上述内容之外,在C++语言中,定义变量的点将确定其初始化顺序与相同转换单元中定义的其他变量的关系.这也是用户意图的一部分,即编译器在没有您的帮助的情况下无法做出的决定.

  • @volerag:如果头文件包含在多个实现文件中(这是头文件的目的),在头文件中定义它将产生多个定义.这是ODR违规,这是一个错误.换句话说,它与在头文件中定义普通变量相同 - 它将导致ODR错误. (3认同)
  • @volerag 请注意答案中指出这不再是关键原因的部分。局部静态变量可以在“内联”函数中使用,并且无论从多少个位置调用这些变量,甚至从不同的源文件调用,这些变量都将引用同一个对象。如果 C++ 委员会决定放弃这一要求,他们可以随时这样做。 (2认同)