【发布时间】: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 并且它可以工作。
我这个行为竟然定义明确?是否取决于编译/链接顺序?
我该如何解决?
谢谢
【问题讨论】:
-
未指定在不同翻译单元中定义的全局变量的初始化顺序。在您的情况下,
colors在Red和Magenta之前被初始化。我认为,但不确定,标记构造函数本身constexpr可能会有所帮助,如constexpr Color(int r_, int g_, int b_) : r(r_), g(g_), b(b_) {} -
听起来很有希望,但事实并非如此......为什么类本身的类型不完整?这是防止成员无限递归的唯一方法吗?