我目前正在将我的项目从Windows移植到Linux。
该项目由一个主要的'共享库,几个插件(也是共享库)和一个启动器应用程序。
在' main'共享库那里有一个模板单例类,另一个类可以继承使用单例模式。
模板单例类的实现如下:
template<class T>
class Singleton
{
public:
static T* getInstance()
{
if(!m_Instance)
{
m_Instance = new T();
}
return m_Instance;
}
private:
static T* m_Instance;
protected:
Singleton()
{
assert(!m_Instance);
m_Instance = (T*)this;
}
~Singleton()
{
m_Instance = 0;
}
};
template<class T> T* Singleton<T>::m_Instance = 0;
继承自Singleton类的类是 - 例如 - Logger类。 所以每当我打电话
Logger::getInstance()
我得到了一个有效的记录器类实例。
对于Windows,这适用于多个DLL。
如果我在&#39; main&#39;中实例化记录器。 dll并尝试在插件A和B中获取实例,它总是返回相同的实例。
在Linux上但是我无法重现这种行为。对于插件A和B,断言
assert(!m_Instance);
触发器,程序停止。
我需要做些什么来获得与Windows中使用dll相同的行为?
我尝试使用-rdynamic进行链接,但不幸的是,这并没有解决问题。
答案 0 :(得分:0)
恕我直言,你能得到的最接近你的要求就是使用following pattern:
#include <iostream>
template<class Derived>
class Singleton {
public:
static Derived& instance() {
static Derived theInstance;
return theInstance;
}
protected:
Singleton() {}
private:
Singleton(const Singleton<Derived>&);
Singleton<Derived>& operator=(const Singleton<Derived>&);
};
class ASingleton : public Singleton<ASingleton> {
public:
void foo() { std::cout << "foo() called ..." << std::endl; }
};
int main() {
ASingleton& a = ASingleton::instance();
a.foo();
return 0;
}
无论您希望通过接口访问什么,都可以使用多重继承来注入。虽然使用Singleton<Derived>
基类的好处有点可疑,但它只提供了狭窄的instance()
实现。