对于C++类中的静态成员变量-初始化是在类外部完成的。我想知道为什么?对此有什么逻辑上的推理/约束吗?或者它是纯粹的遗留实现--标准不想纠正它?
我认为在类中进行初始化更“直观”,更少的confusing.It也给人一种变量的静态和全局的感觉。例如,如果您看到静态常量成员。
发布于 2010-12-29 01:02:36
从根本上说,这是因为为了不违反One-Definition Rule,必须在一个转换单元中定义静态成员。如果语言允许这样的东西:
struct Gizmo
{
static string name = "Foo";
};
则将在对该头文件进行翻译(#include
)的每个翻译单元中定义name
。
C++确实允许您在声明中定义完整的静态成员,但您仍然必须在单个转换单元中包含定义,但这只是一种捷径,或者说是语法糖。因此,这是允许的:
struct Gizmo
{
static const int count = 42;
};
只要a)表达式是const
整型或枚举类型,b)表达式可以在编译时求值,c)仍然有一个定义不违反one定义规则:
文件: gizmo.cpp
#include "gizmo.h"
const int Gizmo::count;
发布于 2010-12-29 01:22:59
在C++中,从一开始,初始化器的存在就是对象定义的独占属性,也就是说,带有初始化器的声明总是一个定义(几乎总是)。
正如您必须知道的,C++程序中使用的每个外部对象必须定义一次,并且仅在一个翻译单元中定义一次。允许静态对象的类内初始化器将立即违反这一约定:初始化器将进入头文件(类定义通常驻留在那里),从而生成同一静态对象的多个定义(每个包含头文件的翻译单元一个定义)。当然,这是不可接受的。出于这个原因,静态类成员的声明方法完全是“传统的”:您只需在头文件中声明它(即不允许初始化器),然后在您选择的转换单元中定义它(可能使用初始化器)。
此规则的一个例外是整型或枚举类型的常量静态类成员,因为此类条目可以用于整型常量表达式(ICE)。ICEs的主要思想是在编译时计算它们,因此不依赖于所涉及的对象的定义。这就是为什么这个异常对于整型或枚举类型是可能的。但是对于其他类型,它只会与C++的基本声明/定义原则相矛盾。
发布于 2010-12-29 00:52:19
这是因为代码的编译方式。如果在类中初始化它,每次包含头文件时,都会得到静态变量的一个实例。这绝对不是我们的意图。在类外部初始化它使您可以在cpp文件中初始化它。
https://stackoverflow.com/questions/4547660
复制相似问题