首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >C++静态成员变量及其初始化

C++静态成员变量及其初始化
EN

Stack Overflow用户
提问于 2010-12-29 00:46:32
回答 5查看 51.9K关注 0票数 50

对于C++类中的静态成员变量-初始化是在类外部完成的。我想知道为什么?对此有什么逻辑上的推理/约束吗?或者它是纯粹的遗留实现--标准不想纠正它?

我认为在类中进行初始化更“直观”,更少的confusing.It也给人一种变量的静态和全局的感觉。例如,如果您看到静态常量成员。

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2010-12-29 01:02:36

从根本上说,这是因为为了不违反One-Definition Rule,必须在一个转换单元中定义静态成员。如果语言允许这样的东西:

代码语言:javascript
运行
复制
struct Gizmo
{
  static string name = "Foo";
};

则将在对该头文件进行翻译(#include)的每个翻译单元中定义name

C++确实允许您在声明中定义完整的静态成员,但您仍然必须在单个转换单元中包含定义,但这只是一种捷径,或者说是语法糖。因此,这是允许的:

代码语言:javascript
运行
复制
struct Gizmo
{
  static const int count = 42;
};

只要a)表达式是const整型或枚举类型,b)表达式可以在编译时求值,c)仍然有一个定义不违反one定义规则:

文件: gizmo.cpp

代码语言:javascript
运行
复制
#include "gizmo.h"

const int Gizmo::count;
票数 40
EN

Stack Overflow用户

发布于 2010-12-29 01:22:59

在C++中,从一开始,初始化器的存在就是对象定义的独占属性,也就是说,带有初始化器的声明总是一个定义(几乎总是)。

正如您必须知道的,C++程序中使用的每个外部对象必须定义一次,并且仅在一个翻译单元中定义一次。允许静态对象的类内初始化器将立即违反这一约定:初始化器将进入头文件(类定义通常驻留在那里),从而生成同一静态对象的多个定义(每个包含头文件的翻译单元一个定义)。当然,这是不可接受的。出于这个原因,静态类成员的声明方法完全是“传统的”:您只需在头文件中声明它(即不允许初始化器),然后在您选择的转换单元中定义它(可能使用初始化器)。

此规则的一个例外是整型或枚举类型的常量静态类成员,因为此类条目可以用于整型常量表达式(ICE)。ICEs的主要思想是在编译时计算它们,因此不依赖于所涉及的对象的定义。这就是为什么这个异常对于整型或枚举类型是可能的。但是对于其他类型,它只会与C++的基本声明/定义原则相矛盾。

票数 13
EN

Stack Overflow用户

发布于 2010-12-29 00:52:19

这是因为代码的编译方式。如果在类中初始化它,每次包含头文件时,都会得到静态变量的一个实例。这绝对不是我们的意图。在类外部初始化它使您可以在cpp文件中初始化它。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4547660

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档