我正在使用自己的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;
}
您可以使您的工厂变量成为指针(初始化为null),然后让您的REGISTER_OBJECT宏实例化它,即将其设置为新的std :: map ...如果它为null。
本文(基本上)将单例模式合并到类中使得我的静态变量不会被创建两次(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()
访问它