我面临以下问题:
我有一个 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。 我查了一下,发现首先调用了空构造函数(这没有意义,原因很快就会揭示),然后我将空构造函数更改为:
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。
在运行时我可以使用 static const Colors 并且它有效。
我对这种行为有明确的定义吗?是否取决于编译/链接顺序?
我该如何解决?
谢谢
最佳答案
您正在遇到 Static Initialization Order Fiasco .听起来你的 colors
数组在 Red
和 Magenta
对象之前被初始化。
一个解决方案是 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() };
关于c++ - 在 C++ 中使用静态常量成员初始化另一个静态常量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44229029/