It happens so that I have a need of the infamous singleton pattern. Better yet, it happens so that I have a need of infamous C++ templates in combination with that pattern. So, what troubles me is this:
template <class T>
class PDatabaseTable
{
...
static PDatabaseTable <T> & instance()
{
static PDatabaseTable <T> singleton;
return singleton;
}
...
};
This is a typical way to implement a singleton that's supposed to be created on the first use. Now, here we have a static variable singleton. Since the instance() function may be called from several different modules, the question is: will there be only one instance of the object for any given type T, or will every module instantiate its very own singleton?
There will only be one instance for each type T, just as, if it weren't a template, there would only be one instance.
The function is inline, meaning that although it can be defined in multiple compilation units, after linking there will be only one version of it, and only one instance of any local static objects.
Your singleton is called Meyers Singleton and you can find an explanation about thread safety of this singleton type in Static locals and threadsafety in g++ article which nicely explains how static local variables are thread-safe to create.
Definitely there will be only one instance.
I am just wondering why can't you move that static object out of function to the class body ?
template <class T>
class PDatabaseTable
{
static PDatabaseTable <T> singleton;
static PDatabaseTable <T> & instance()
{
return singleton;
}
};
template<class T>
PDatabaseTable<T> PDatabaseTable<T>::singleton;
You CAN move the init of the static outside of the class body, and this is also possible for the static function.
template <typename T>
class Singleton
{
public:
static Singleton<T>* Singleton::getInstance();
T* getMember() { member_; }
protected:
Singleton() { member_ = new T; }
~Singleton() { if (singleton_) delete member_; }
private:
static Singleton<T>* singleton_;
T* member_;
};
template <typename T>
Singleton<T>* Singleton<T>::getInstance()
{
if (NULL == singleton_) singleton_ = new Singleton;
return singleton_;
}
template <typename T>
Singleton<T>* Singleton<T>::singleton_ = NULL;
Related
I implemented a singleton class in c++ using double checked lock(with safe locks), it works. Then I try to convert it into template version, like this:
// singleton.h
#include <atomic>
#include <mutex>
template<typename T>
struct singleton {
~singleton() {}
static singleton<T>* getInstance(std::mutex& m);
static std::atomic<singleton<T>*> m_instance; // this is the problem.
};
template<typename T>
singleton<T> * singleton<T>::getInstance(std::mutex& m) {
auto temp = m_instance.load(std::memory_order_acquire);
if (temp == nullptr) {
std::lock_guard<std::mutex> lock(m);
temp = m_instance.load(std::memory_order_relaxed);
if (temp == nullptr) {
temp = new singleton();
m_instance.store(temp, std::memory_order_release);
}
}
return temp;
}
Then in a .cpp file I wish to use this class. Note the storage of static std::atomic<singleton<T>*> m_instance needs to exist in my .cpp file, so I tried this:
struct M {
int m_i;
static std::mutex m;
};
std::atomic<singleton<M>*> singleton<M>::m_instance; // error:
nullity) {
auto instance1 = singleton<M>::getInstance(M::m);
auto instance2 = singleton<M>::getInstance(M::m);
}
The line of m_instance definition reports:
template specialization requires 'template<>'
std::atomic<singleton<M>*> singleton<M>::m_instance;
How to fix this syntax error? Thanks.
Don't try to explicitly specialize the static data member, just define it for the primary template itself (in the header file):
template<typename T>
std::atomic<singleton<T>*> singleton<T>::m_instance{nullptr};
Alternatively mark m_instance in the class template definition as inline (since C++17) and add the {nullptr} initialization there. (Beware that you must initialize explicitly to nullptr. The default constructor of std::atomic does not perform proper initialization before C++20.)
There is no need to add anything in the source file.
The whole thing is extremely redundant though, since the compiler will add the whole locking mechanism to dynamic initialization of a local static storage duration variable anyway (since C++11). You don't need to do anything manually. The common approach is to define the singleton as
static auto& getInstance() {
static singleton<T> instance;
return instance;
}
without a static data member, or if the dynamic storage duration is important to you
static auto& getInstance() {
static auto instance = std::make_unique<singleton<T>>();
return *instance;
}
I was looking into Alexandrescu's singleton created with policies, which is an interesting design. (http://loki-lib.sourceforge.net/html/a00670.html)
However, he first explains that you should guarantee a Singleton's uniqueness, which I agree with. But when you look at the policy implementation, he has a policy CreateWithNew which invokes the new operator on the argument provided with T. which means the constructor has to be public, meaning any user creating the singletonHolder can also instantiate that class directly himself.
Obviously it is still a nice design, but I just wanted to make sure if I missed something important or if he sacrificed the uniqueness for a versatile design.
Thanks!
A test example:
The following class has a TestObject which is the Singleton class, and a simple createViaNewPolicy which just uses new to allocate the singleton. notice that the constructor of TestObject has to be public in order for this to work.
//////////////////////////////////////////////////////////////////////////
class TestObject
{
public: // change this to private (to guarantee uniqueness) but then it wont compile
TestObject() {}
int foo() {return 1;}
~TestObject() {}
};
//////////////////////////////////////////////////////////////////////////
template< class T, template <class> class CreationPolicy >
class SingletonHolder
{
public:
T* SingletonHolder<T, CreationPolicy>::Instance()
{
if (!pInstance_)
{
pInstance_ = CreationPolicy<T>::Create();
}
return pInstance_;
}
private:
static T* pInstance_;
};
template< class T, template <class> class CreationPolicy >
T* SingletonHolder<T, CreationPolicy>::pInstance_;
//////////////////////////////////////////////////////////////////////////
template<class T>
class CreateViaNew
{
public:
static T* Create()
{
return new T();
};
};
//////////////////////////////////////////////////////////////////////////
int _tmain(int argc, _TCHAR* argv[])
{
SingletonHolder<TestObject, CreateViaNew> mySingletonHolder;
TestObject* testObj = mySingletonHolder.Instance();
return 0;
}
CreateUsingNew is just the policy. They way it's used is as a template template parameter inside the Singleton class. So the singleton class will have the following layout (exctract from modern C++ design) :
class Singleton
{
Singleton& Instance();
... operations...
public:
Singleton();
Singleton(Singleton const&);
Singleton& operator=(Singleton const&);
~Singleton();
}
There the creation of the object can only be done through the Instance method. In turn that method reads (extract from the link to Loki) :
template
<
class T,
template <class> class CreationPolicy,
... some other arguments...
>
void SingletonHolder<T, CreationPolicy,
...some other arguments...>::MakeInstance()
{
... stuff ...
if (!pInstance_)
{
if (destroyed_)
{ /* more stuff */ }
pInstance_ = CreationPolicy<T>::Create();
/* even more stuff */
}
}
So the line where the magic happens is pInstance = CreationPolicy<T>::Create();
Itself, every construction method for a Singleton object is private and underlying implementation of the construction policy can only be accessed through the public MakeInstance method
I am not sure what to call it, but is something like this possible as the commented out line reflects?
template <typename T>
class Test
{
public:
Test(T& t) : m_t(t) {}
T* operator->() { return &m_t; }
private:
T& m_t;
};
class A
{
public:
static const int integer = 0;
void function() {}
};
int main()
{
A a;
Test<A> test(a);
test->function();
// Something similar to doing Test<A>::integer?
return 0;
}
Well, why don't you do:
test->integer;
You can always access static members the same way as non-static ones (i.e. from an instance variable).
The other option would be to define in Test:
template <typename T>
class Test
{
public:
typedef T value_type;
// ...
};
In which case you will be able to do:
Test<A>::value_type::integer;
which will avoid the need of creating an instance of Test<A>.
At last, if you are using C++11 and Test follows the smart pointers conventions, then you will have:
std::pointer_traits<Test<A> >::element_type::integer;
which has the advantage to work even if you replace Test<A> with A*.
No. In C++, "overloading" only makes sense for functions. Instead of mixing static and non-static items in a class, you could try making two separate classes, both with all non-static members. Return your value from a function call, rather than using a public static member variable.
Closed. This question is off-topic. It is not currently accepting answers.
Want to improve this question? Update the question so it's on-topic for Stack Overflow.
Closed 10 years ago.
Improve this question
The following code is my implementation of the Singleton Pattern.
#include <iostream>
template<class T>
class Uncopyable
{
protected:
Uncopyable(){}
~Uncopyable(){}
private:
Uncopyable(const Uncopyable<T>&);
Uncopyable& operator=(const Uncopyable<T>&);
};
template <class T>
class Singleton : private Uncopyable<T>
{
public:
static T* getInstancePtr()
{
return instance;
}
protected:
Singleton<T>()
{
if(instance == 0)
{
instance = new T();
}
};
~Singleton<T>()
{
};
private:
static T* instance;
};
template<class T> T* Singleton<T>::instance = 0;
class Test : public Singleton<Test>
{
public:
Test(){};
~Test(){};
inline void test() const
{
std::cout << "Blah" << std::endl;
}
private:
friend class Singleton<Test>;
protected:
};
int main(int argc, char* argv[])
{
Test* t = Test::getInstancePtr();
Test* t2 = Test::getInstancePtr();
t->test();
t2->test();
return 0;
}
It works in this form, however I am uncertain as to whether it really is correct due to the constructor and destructor of the Singleton being protected as opposed to being private. If I declare them as private the code will not compile as they are not accessible to the class. Is this implementation safe to use, or is there anything I can do to improve it to ensure only one instance will be created and used.
Thanks
That is most certainly an incorrect implementation of singleton. There are too many issues with that implementation.
In C++11, you can make use of std::call_once and std::once_flag to implement singleton pattern. Here is one example:
//CRTP base singleton class
template<typename TDerived>
class Singleton
{
static std::unique_ptr<TDerived> m_instance;
static std::once_flag m_once;
protected:
Singleton() {}
public:
~Singleton() { }
static TDerived & GetInstance()
{
std::call_once
(
Singleton::m_once,
[] (){ Singleton::m_instance.reset( new TDerived() ); }
);
return *m_instance;
}
};
template<typename TDerived>
std::unique_ptr<TDerived> Singleton<TDerived>::m_instance;
template<typename TDerived>
std::once_flag Singleton<TDerived>::m_once;
Now you can derive from it as:
class Demo : public Singleton<Demo>
{
public:
void HelloWorld() { std::cout << "HelloWorld" << std::endl; }
};
//call HelloWorld() function through singleton instance!
DemoSingleton::GetInstance().HelloWorld();
There are several things wrong with the code you've posted.
The Uncopyable class doesn't need to be templated
The Singleton class isn't thread safe
Your Singleton instance is never deleted
I would re-implement your accessor as:
static T& GetInstance()
{
static T instance;
return instance;
}
Then make sure you call Singleton<T>::GetInstance() in the main thread of your application (during initialisation) to avoid any threading issues.
your destructor private will cause the compile error?cause when the process ends,the compile cannot call the private function so the object cannot be delete
No this is not a good implementation of the singleton pattern, it does not work!
The only instance of Test in the example is NULL! The constructor is never called!
You need to change Singleton::getInstancePtr to:
public:
static T* getInstancePtr()
{
if(instance == 0)
{
instance = new T();
}
return instance;
}
protected:
Singleton<T>() {};
The constructor for Test will now be called.
Usually singleton objects live for the lifetime of the program, so I do not implement them like that, because you use dynamic allocation, then someone must free it and you return a pointer to your singleton object, then you may accidentally delete it, so I will use something like this:
template< class T >
struct Singleton : Uncopyable<T> {
public:
static T& get_instance() {
static T res;
use( res ); // make sure object initialized before used
return res;
}
private:
static void use( T& ) {}
};
There is no correct implementation of the Singleton anti-pattern in C++.
The main issues with this attempt are:
The semantics are a very weird and error-prone; you must instantiate Singleton somewhere in order to create the instance. You example never creates the instance, and t->test() is erroneously calling a function via a null pointer.
Construction is not thread-safe; two instances could be created if two unsynchronised threads both instantiate Singleton.
If the instance is actually created, then it is leaked.
A less erroneous implementation might be more like this:
template <typename T>
T & singleton()
{
static T instance;
return instance;
}
but this still has issues: in particular, the instance may be destroyed before other static objects, which may attempt to access it in their destructors.
Is it possible to make a generic singleton? I want to create something I can just inherit from and get the functionality of a singleton. I'm having trouble with using templates with static members.
Shouldn't this work?
**
UPDATED
**
Thanks for the replies so far. So now my problem is that GameEngine can't see it's own constructor. I know it's private but still.
Singleton.h
template <typename T>
class Singleton
{
private:
static std::shared_ptr<T> m_Instance;
public:
static std::shared_ptr<T> Instance();
};
template<typename T>
std::shared_ptr<T> Singleton<T>::m_Instance = nullptr;
template<typename T>
std::shared_ptr<T> Singleton<T>::Instance()
{
if(m_Instance == nullptr)
m_Instance = std::make_shared<T>();
return m_Instance;
}
GameEngine.h
class GameEngine : public Singleton<GameEngine>
{
private:
GameEngine();
};
I don't see how that'd work, since there's nothing preventing you from creating more instances of GameEngine.
Even if it were possible (and it is) to have a generic way of creating a singleton (perhaps involving macros), I would advise against it, because situations where you actually want singletons are rare. Let me rephrase that... situations where you actually really need a singleton are rare.
The best way to create a singleton is as follows:
class GameEngine
{
public:
static GameEngine& instance() { static GameEngine e; return e; }
private:
GameEngine() {}
GameEngine(const GameEngine&) = delete;
};
The e variable will be (thread-safely) initialized on first call to instance, and it will be destroyed on orderly process exit. The private/deleted constructors prevent a second instance from ever being created.