kum*_*ran 48 c++ initialization static-variables
对于C++类中的静态成员变量 - 初始化在类外部完成.我想知道为什么?对此有任何逻辑推理/约束吗?或者它是纯粹的遗留实现 - 标准不想纠正?
我认为在类中初始化更"直观"而且不那么混乱.它还给出了变量的静态和全局性.例如,如果您看到静态const成员.
Joh*_*ing 37
从根本上说,这是因为静态成员必须只在一个翻译单元中定义,以免违反单一定义规则.如果语言允许这样的话:
struct Gizmo
{
static string name = "Foo";
};
Run Code Online (Sandbox Code Playgroud)
然后name
将在每个翻译单元中定义#include
该头文件.
C++允许您在声明中定义完整的静态成员,但您仍然必须在单个翻译单元中包含一个定义,但这只是一个快捷方式或语法糖.所以,这是允许的:
struct Gizmo
{
static const int count = 42;
};
Run Code Online (Sandbox Code Playgroud)
只要a)表达式是const
整数或枚举类型,b)表达式可以在编译时计算,并且c)在某个地方仍然存在一个不违反一个定义规则的定义:
file:gizmo.cpp
#include "gizmo.h"
const int Gizmo::count;
Run Code Online (Sandbox Code Playgroud)
AnT*_*AnT 12
在C++中,从一开始,初始化器的存在就是对象定义的独有属性,即带初始化器的声明总是一个定义(几乎总是).
您必须知道,C++程序中使用的每个外部对象必须只在一个转换单元中定义一次且仅定义一次.允许静态对象的类内初始化器将立即违反此约定:初始化器将进入头文件(类定义通常驻留在其中),从而生成相同静态对象的多个定义(每个包含头文件的转换单元一个) ).这当然是不可接受的.出于这个原因,静态类成员的声明方法完全是"传统的":你只在头文件中声明它(即不允许初始化器),然后你在你选择的翻译单元中定义它(可能使用初始化器) ).
此规则的一个例外是针对整数或枚举类型的const静态类成员,因为这些条目可以用于积分常量表达式(ICE).ICE的主要思想是它们在编译时进行评估,因此不依赖于所涉及对象的定义.这就是整数或枚举类型可能出现此异常的原因.但对于其他类型,它只会与C++的基本声明/定义原则相矛盾.