类声明或定义中的静态变量? 我是C++新手。 我有一门课是这样的: class CodeTest { private: static const int TOTAL=100; };
类声明或定义中的静态变量? 我是C++新手。 我有一门课是这样的: class CodeTest { private: static const int TOTAL=100; };,c++,static-members,C++,Static Members,TOTAL是声明还是定义 当我阅读Scott Meyer的书时,有人提到在实现文件中,我们需要定义如下内容: const int CodeTest::TOTAL; 为什么需要这样做?需要在头之外的实现文件中进行声明,因为否则包含此头的每个翻译单元都将定义自己的对象(即,它自己的变量存储) 这将违反法律。结果可能是,如果变量在一个翻译单位中发生了变化,那么其他翻译单位将看不到这种变化。现在,这没有那么重要,因为变量是常量。然而,接受它的地址也会在不同的翻译单位中产生不同的指针。问题的第一部分:
TOTAL
是声明还是定义
当我阅读Scott Meyer的书时,有人提到在实现文件中,我们需要定义如下内容:
const int CodeTest::TOTAL;
为什么需要这样做?需要在头之外的实现文件中进行声明,因为否则包含此头的每个翻译单元都将定义自己的对象(即,它自己的变量存储)
这将违反法律。结果可能是,如果变量在一个翻译单位中发生了变化,那么其他翻译单位将看不到这种变化。现在,这没有那么重要,因为变量是常量。然而,接受它的地址也会在不同的翻译单位中产生不同的指针。问题的第一部分: 此行:
static const int TOTAL=100代码>是一个声明,后跟一个初始化
TOTAL
是一个标识符
问题的第二部分
const int CodeTest::TOTAL
是初始化变量所必需的。由于这引发了一些争议,我查看了标准,而@Nawaz是对的,我错了
9.4.2/2
如果静态
数据成员是常量整型[…]。成员
如果在中使用,则仍应在命名空间范围中定义
程序和命名空间范围定义不应包含
初始化器
这里有一个声明,变量被初始化为一个值。在类之外,必须定义变量,但不能为其赋值
具有const
integral类型的部分仅适用于此特定情况-即,您可以在类内初始化所述类型,但所有静态
数据成员必须在类外定义
要回答这个问题:
无论定义在类外部是否是必需的(取决于是否使用成员),类内部的任何内容(初始化与否)都只是一个声明
static const int TOTAL=100; // is a declaration followed by an initialisation.
从C++标准3.1节:
声明将名称引入翻译单元,或重新声明先前声明引入的名称。声明指定这些名称的解释和属性
下一段说明声明是一个定义,除非。。。。。。它在类定义中声明静态成员:
struct X
{
int a; // defines a
static int b; // declares b
};
您可以在此处阅读有关定义和声明的更多信息:此处有必要输入:@Griwes完全没有帮助。“这是一个很好的问题。”科拉德鲁道夫,每一本像样的书都解释得很好。来吧。@Griwes祝贺你。您刚刚解释了为什么堆栈溢出是完全不必要的。买书就行了。FWW,我花了很长时间才明白这一点,即使阅读了很多(好的和坏的)C++书籍来解释TU是如何工作的。+ 1在一个美丽的星期日下午引起了争论。code>在类外,必须定义变量
,只有在需要该静态变量地址的情况下才必须,否则,您不需要定义它:P@Mr.Anubis如果你不想要有效的C++,你是对的。然而,标准是这样说的。。。(如果你使用它,不仅仅是它的地址)@Mr.Anubis,这还不清楚。关于吕钦引用的段落中“使用”的含义存在相当大的争议。因此,对C++11的措辞进行了修改,以使其更加清晰。对,唯一的问题是,为什么Stroustrup说您可以使用它们而不需要记录地址。@KonradRudolph说的话和他引用的内容有差异:/您的回答没有意义,因为成员函数可以在类本身内部定义,那为什么不是静态成员呢?正如我所说的,完美的答案是,因为标准是这样说的。而且因为R Marthino在聊天中提到了这一点:可以在每个TU中使用静态存储定义一个单独的实例,但这不是我们想要的(通常)!我们希望从所有TU访问一个实例。@Nawaz但这些函数定义为内联的
,所以这不是一回事。@Nawaz成员函数是完全不同的,它们是内联的。见我之前的评论,这有点相关。C++也可以为静态模板类模板做同样的操作,但是这又会创建不同的对象。@ Nawaz Nooooo!代码>内联不是编译器的提示,它决定了链接。是的,就实际内联而言,这是一个提示,但它也决定了链接,这样的函数不会被导出,因此也不会违反ODR。我认为仅仅说“是”或“否”并不是真正的建设性的。TOTAL不是一个变量,正如前面的const
word标记的那样。它是一个常量,它被视为任何常量定义,并且允许编译器在数据区域中为它分配空间。