【问题标题】:Redeclared static class variable [duplicate]重新声明的静态类变量[重复]
【发布时间】:2018-07-12 05:44:54
【问题描述】:

我正在查看我下载的一些代码,我看到以下内容:

class MyClass
{
[...]
    public:
        static double shape;
[...]
};
double MyClass::shape = 1.0;

类型被声明两次似乎很奇怪。为什么需要这样做?

【问题讨论】:

  • 因为static double shape = 1.0; 无法编译?
  • 该类型只声明一次(静态双 MyClass::shape,在类声明中)。静态类成员的初始值在语句 double MyClass::shape = 1.0; 中定义。另见:stackoverflow.com/questions/1410563/…

标签: c++


【解决方案1】:

类定义中的声明,是纯声明。

类定义之后的声明,是一个定义。它为变量分配存储空间。

这样做的一个原因是,对于 static 数据成员,只有整数或 enum 类型,或 constexprC++17 inline 的数据成员可以在类内声明中初始化。


不应将上述定义放在头文件中,因为如果该头文件包含在多个翻译中,则多个定义将违反一个定义规则。

一个简单的解决方案是将直接的static 变量替换为访问器函数:

// OK to place in a header:

class MyClass
{
public:
    static auto shape()
        -> double&
    {
        static double the_shape = 1.0;
        return the_shape;
    }
};

【讨论】:

  • 根据我的经验,将两者分开的主要原因是您(通常)只希望变量存储(定义)一次,但通常希望它为多个源声明文件。因此声明将存在于头文件中(包含在多个源文件中),而定义将只存在于一个源文件中。 (正如现在的答案所说......我会在此处留下此评论,以防任何人澄清措辞差异)
  • @zzxyz:我添加了一些关于该问题的讨论,展示了如何为仅标头模块执行此操作。还有模板化结构技巧(ODR 对模板有特殊豁免)。对于 C++17,我们有 inline 变量,但我不确定当前的编译器是否支持它。
  • 是的,很高兴有新的方法可以做到这一点。旧方法……除了对学习语言的人来说不直观之外,还很痛苦。
  • 好的,我明白了。事实上,声明和定义存在于单个.h 文件中。我现在明白,如果这个文件被多个源文件包含,这会导致问题(事实并非如此)。
  • @bernie:请注意,当前选择的副本“解决方案”有一些不正确的声明。但还有一个正确的微妙之处,即类内初始化对于枚举类型也可以,在标准中它不被视为整数类型。相应地修正了这个答案。
猜你喜欢
  • 2021-10-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-01-31
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多