您的问题似乎确实源于臭名昭著的静态初始化命令惨败。
基本上,当您在一个翻译单元中有一个static
变量,在第二个翻译单元X
中引用另一个static
变量Y
时,您的程序有 50/50 的错误行为机会。为了行为正确,Y
应该在之前初始化,X
但 C++ 不强制执行。
据我所知,处理这个问题的唯一正确方法是使用函数级static
变量,它确保m_array
将在第一次调用时初始化MyClass::array()
(在 C++11 中,甚至可以保证此初始化是线程安全的):
struct MyClass {
static const size_t arraySize = 4;
// This function could be defined in a .cpp rather than inline
// I only put it inside the class for compactness/readability reasons
static const std::string* array() {
static const std::string m_array[arraySize] = {"", "ini", "txt", "bmp"};
return m_array;
}
};
// In some other file
struct OtherClass {
// This function could be defined in a .cpp rather than inline
static void whatever() {
do_something_with(MyClass::array());
}
};
换句话说,您应该避免声明static
全局变量或类变量(除非您绝对确定它们可以解析为编译时常量,arraySize
如上所示),而是将它们包装在函数内部的函数级别static
。
作为旁注,这个习惯用法使您更容易使用适当的容器而不是传统的 C 数组,例如。std::vector
或者,如果您使用的是 C++11,则std::array
:
// C++03
struct MyClass {
// This function could be defined in a .cpp rather than inline
static const std::vector<std::string>& data() {
static std::vector<std::string> m_data;
if (m_data.empty()) {
m_data.push_back("");
m_data.push_back("ini");
m_data.push_back("txt");
m_data.push_back("bmp");
}
return m_data;
}
};
// C++11
struct MyClass {
using Container = std::vector<std::string>;
// or
// using Container = std::array<std::string, 4>;
// This function could be defined in a .cpp rather than inline
static const Container& data() {
static const Container m_data = {"", "ini", "txt", "bmp"};
return m_data;
}
};