我正在尝试实现一个带有注册程序和测试器类实现的小型测试工厂,它在程序启动时向工厂注册(从实际实现中删除代码,因此可能无法编译;此外,请忽略getInstance在TestFactory中的线程问题,删除该代码以进行简化)。
class Base {
public:
virtual int test() = 0;
virtual int createTestMsg() = 0 ;
};
typedef Base* (*pfn)();
class TestFactory {
public:
Base *getTester(int type) {
auto iter = mTesterRegistry.find(type);
if (mTesterRegistry.end() != iter) {
return iter->second();
}
return NULL;
}
TestFactory * getInstance() {
static TestFactory* ptr = new TestFactory();
mInstance.reset(ptr);
return ptr;
}
private:
static std::map<int, pfn> mTesterRegistry;
static std::unique_ptr<TestFactory> mInstance;
};
class Registrar {
public:
Registrar(MessageTypes type, pfnGetTester creator) {
TestFactory::getInstance()->registerType(type, creator);
}
};
// this is the test class implementation
class ToTest : public Base {
private:
static Registrar & registerMe();
static Registrar & mRegistrar;
};
// test class cpp file.
Registrar &ToTest::mRegistrar = ToTest::registerMe();
Registrar & ToTest::registerMe() {
static Registrar registrar(int,
[]() -> Base * {return new ToTest();} );
return registrar;
}问题在于,在这种初始化方法中,编译器直到编译单元加载到内存中(首次调用)时才创建mRegistrar对象。有更好的方法来处理这种情况吗?
发布于 2014-10-14 08:48:16
据我所知,没有任何可靠的方法。该语言的定义使得静态作用域对象的动态初始化可以在第一次使用之前的任何时候进行。只保证在main之前进行零和常量初始化。我认为,C++14规则稍微改变了一些,其中包含了constexpr函数和构造函数。
最近我遇到了一种非常糟糕的初始化争用条件(VS2010,静态初始化器不是线程安全的),最后我不得不使用这个原子双检查锁方法来初始化变量。事实上,这是一个恼人的小问题,很难复制和发现错误,以至于我因为它失去了我的工作--我甚至不知道我的最后一次尝试是否成功,而且可能永远也不会成功。如果您找到了一种方法来保证在某个已知点上的动态初始化,但没有确保在旋转线程之前调用main (或者DllMain或其他任何东西)中的任何一件事情,我当然也想知道。除此之外,我还要遵循一条规则,在11岁前的MT环境中,不要使用静态变量,除非我有自杀倾向。
https://stackoverflow.com/questions/26355824
复制相似问题