静态成员变量初始化两次

时间:2015-05-17 01:07:58

标签: c++ static initialization

我使用自己的REGISTER_OBJECT()宏来创建一个充满类的工厂。 除了我的静态std :: map变量的初始化之外,它按预期工作。如果我没有在.cpp文件中初始化静态std :: map,我当然会得到一个未解析的外部符号。但问题是,我必须在运行时首先调用的.cpp文件中初始化。否则,将在std :: map初始化程序之前调用REGISTER_OBJECT()。

//std::map MUST be initialized in the .cpp file the compiler calls first.

    std::map<std::string, MyFactory*> Factory::factories; //global init
    REGISTER_OBJECT(MyClass);

如果我将std :: map初始化器放在我喜欢的.cpp文件中,REGISTER_OBJECT将被调用几次,std :: map将相应地填充,但是然后std :: map行会命中并且变量被重置。

我是如何确保在调用REGISTER_OBJECT之前初始化std :: map而不将其放在另一个.cpp文件中。谢谢:))

//Factory.cpp
std::map<std::string, MyFactory*>* Factory::factories = NULL;

void Factory::Register(const std::string& name, MyFactory* _class)
{
    if(!factories){ factories = new std::map<std::string, MyFactory*>(); }
    (*factories)[name] = _class;
}

2 个答案:

答案 0 :(得分:2)

你可以使你的工厂变量成为指针(初始化为null),然后让你的REGISTER_OBJECT宏实例化它,即将它设置为新的std :: map ...如果它是null。

答案 1 :(得分:0)

这篇(基本上)将单例模式合并到类中的文章阻止了我的静态变量被创建两次(https://isocpp.org/wiki/faq/ctors#static-init-order-on-first-use-members

基本要点是替换

class MyClass {
  // static member gets initialized twice
  static inline int someNumber = randomInt(); 
}

...和...

class MyClass {
  // singleton like pattern keeps someNumber from being initialized more than once
  static inline int& someNumber() {
    static int* singletonHack = randomInt();
    return &singletonHack;
  }
}

然后像这样MyClass::someNumber()