0

我有一个程序,我在其中编写了一个类,如下所示:

.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;
}

工作正常。第一种情况有什么问题?我不能在静态函数中访问静态成员变量吗?

4

2 回答 2

3

在第一种情况下,您尝试访问您应该初始化的对象 (_someMap)。_someMap 尚未在那里初始化。

于 2013-05-31T09:43:57.747 回答
1

C++ 保证_someMap在同一个 *.cpp 文件中的任何其他函数作为 .cpp 中语句的(直接或间接)结果调用之前,将初始化具有静态存储持续时间的对象main

但初始化过程_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;
}

这是“第一次使用时构造”的成语。

既然获取地图的唯一方法是调用 function ,那么在调用构造函数并且对象已填充其初始数据someMap()之前,任何东西都不会意外使用它。std::map

于 2013-05-31T18:20:27.397 回答