我有一个程序,我按如下方式编写了一个类:
.h文件
typedef map<string, int> stringMap;
class SampleClass{
public:
void setup();
void update();
void draw();
private:
static stringMap _someMap;
static stringMap someMapInitializer();
};
.cpp文件
//Initializer for static var
stringMap SampleClass::_someMap = someMapInitializer();
stringMap SampleClass::someMapInitializer(){
_someMap["something"] = 1;
return _someMap;
}
但是在执行上述操作后,我开始在运行程序时收到“程序接收信号EXC_BAD_ACCESS”错误(尽管编译正常)
以上功能更改为:
stringMap SampleClass::someMapIntializer(){
map<string, int> m;
m["somehting"] = 1;
return m;
}
工作正常。第一种情况有什么问题?我不能在静态函数中访问静态成员变量吗?
答案 0 :(得分:3)
在第一种情况下,您尝试访问应该初始化的对象(_someMap)。 _someMap尚未在那里初始化。
答案 1 :(得分:1)
C ++保证具有静态存储持续时间的对象_someMap
将在同一* .cpp文件中的任何其他函数被调用为main
中的语句的(直接或间接)结果之前进行初始化。 / p>
但初始化_someMap
的过程涉及调用函数_someMapInitializer()
。如果该函数返回,将使用移动构造函数或复制构造函数创建_someMap
,并传递返回的值。但是_someMapInitializer()
然后尝试在尚未构造的对象_someMap
上调用成员函数。未定义的行为。
对于修复,我设计它更像......
class SampleClass {
//...
private:
static stringMap& someMap();
static void someMapInitializer(stringMap&);
};
stringMap& SampleClass::someMap() {
static bool init_done = false;
static stringMap the_map;
if (!init_done) {
someMapInitializer(the_map);
init_done = true;
}
return the_map;
}
void SampleClass::someMapInitializer(stringMap& the_map) {
the_map["something"] = 1;
}
这是“首次使用时构造”的习语。
现在,获取地图的唯一方法是调用函数someMap()
,在调用std::map
构造函数并且对象已填充其对象之前,没有任何方法可以意外地使用它初始数据。