【问题标题】:using static const member to initialize another static const in c++在 C++ 中使用静态常量成员初始化另一个静态常量
【发布时间】:2017-05-28 23:40:04
【问题描述】:

我面临以下问题:

我有一个 Color 类,就这个问题而言,它简化为:

// Color.h
struct Color {
    int r,g,b;
    Color() : r(0), g(0), b(0) {}
    Color(int r_, int g_, int b_) : r(r_), g(g_), b(b_) {}
    static const Color Red;
    static const Color Magenta;
};

// Color.cpp
#include "Color.h"
const Color Color::Red (255,0,0);
const Color Color::Magenta (255,0,255);

即,我想使用类名作为一些预定义颜色的范围。

现在我在全局范围内的用户文件中:

//user.cpp
#include "Color.h"
static const Color colors[2] = { Color::Red, Color::Magenta };

当我使用 colors[i] 时,我看到它们被 0 填充。 我查了一下,发现首先调用了空构造函数(这没有意义,原因很快就会揭示),然后我将空 c'tor 更改为:

    Color() : r(200), g(200), b(200) {}

得到了同样的结果。

我尝试将颜色定义为 constexpr,如下所示:

    static constexpr Color Red (255, 0, 0);

但它说: 数字常量之前的预期标识符

然后像这样:

    static constexpr Color Red = {255, 0, 0};

像这样:

    static constexpr Color Red = Color(255, 0, 0);

但随后编译失败,因为“'Color' 未在此范围内声明”和“Red 的类型不完整”(真的吗?) 因此,现在使用空 c'tor 确实没有意义,而是将整个内存初始化为 0。

在运行时我可以使用静态 const Colors 并且它可以工作。

我这个行为竟然定义明确?是否取决于编译/链接顺序?

我该如何解决?

谢谢

【问题讨论】:

  • 未指定在不同翻译单元中定义的全局变量的初始化顺序。在您的情况下,colorsRedMagenta 之前被初始化。我认为,但不确定,标记构造函数本身constexpr 可能会有所帮助,如constexpr Color(int r_, int g_, int b_) : r(r_), g(g_), b(b_) {}
  • 听起来很有希望,但事实并非如此......为什么类本身的类型不完整?这是防止成员无限递归的唯一方法吗?

标签: c++ static constants


【解决方案1】:

您遇到了Static Initialization Order Fiasco。听起来您的 colors 数组在 RedMagenta 对象之前被初始化。

一个解决方案是Construct On First Use Idiom

// Color.h
struct Color {
    int r,g,b;
    Color() : r(0), g(0), b(0) {}
    Color(int r_, int g_, int b_) : r(r_), g(g_), b(b_) {}
    static const Color& Red();
    static const Color& Magenta();
};

// Color.cpp
#include "Color.h"
const Color& Color::Red()
{ static const Color red(255,0,0); return red; }
const Color& Color::Magenta()
{ static const Color magenta(255,0,255); return magenta; }

//user.cpp
#include "Color.h"
static const Color colors[2] = { Color::Red(), Color::Magenta() };

【讨论】:

  • 谢谢,但我不喜欢使用单一颜色,特别是这些颜色已经被广泛使用,我只需要一次静态数组。也许我应该在这种情况下使用它(制作“颜色”一个函数)..
猜你喜欢
  • 2019-03-04
  • 2011-10-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-02-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多