问题
I'm currently porting my project from Windows to Linux.
The project consists of a 'main' shared library, several plugins (also shared libraries) and a launcher application.
Within the 'main' shared library there's a template singleton class another class can inherit from to use the singleton pattern.
The template singleton class is implemented as follows:
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;
A class that inherits from the Singleton class is - for example - the Logger class. So whenever I call
Logger::getInstance()
I get a valid instance of the logger class.
For windows this works across multiple DLLs.
If I instantiate the logger in the 'main' dll and try to get the instance in plugin A and B, it'll always return the same instance.
On Linux however I can not reproduce this behavior. For both plugin A and B the assert
assert(!m_Instance);
triggers and the program stops.
What do I have to do to get the same behavior as I have in Windows with dlls?
I tried linking with -rdynamic but unfortunately this didn't solve the problem.
回答1:
IMHO the closest thing you can get that suffices your requirements is something using the 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;
}
Whatever you want to be accessible through an interface might be injected using multiple inheritance. Though the benefit of using a Singleton<Derived> base class is a bit questionable, it just provides that narrow instance() implementation.
来源:https://stackoverflow.com/questions/22998019/template-singleton-base-class-in-shared-object