我目前正在将我的项目从Windows移植到Linux。
该项目由一个“主”共享库,几个插件(也是共享库)和一个启动程序。
在“主”共享库中有一个模板单例类,另一个类可以inheritance使用单例模式。
模板单例类实现如下:
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类inheritance的类是 – 例如 – Logger类。 所以每当我打电话
Logger::getInstance()
我得到了一个logging类的有效实例。
对于Windows来说,这可以跨越多个DLL。
如果我在“主”dll中实例化logging器,并尝试在插件A和B中获取实例,它将始终返回相同的实例。
在Linux上,但是我不能重现这种行为。 对于插件A和B都声明
assert(!m_Instance);
触发器和程序停止。
我必须做什么才能获得与Windows中使用dll一样的行为?
我尝试链接-rdynamic,但不幸的是这并没有解决问题。
恕我直言,你可以得到满足你的要求的最接近的东西是使用以下模式的东西:
#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()
实现。