C++: static member of template singleton class doesn't get compiled/linked - c++

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;
}

Related

Singleton with make_ptr, why not? [duplicate]

I have a singleton class with a private constructor. In the static factory method I do the following:
shared_ptr<MyClass> MyClass::GetInstance()
{
static once_flag onceFlag;
call_once(onceFlag, []() {
if (_instance == nullptr)
_instance.reset(new MyClass());
});
return _instance;
}
If I use
_instance = make_shared<MyClass>();
the code does not compile. My question is: why new can invoke a private constructor but make_shared not?
As mentioned, std::make_shared or its component parts don't have access to private members.
the call_once and once_flag are un-necessary. They are implicit in c++11 static initialisation,
You normally would not want to expose the shared pointer.
class MyClass
{
MyClass() {}
public:
static MyClass& GetInstance()
{
static auto instance = MyClass();
return instance;
}
};
However, there is one case I can imagine where you would want to expose a shared pointer to the impl - this is in the case where the class can choose to 'break off' or 'reset' the impl to a new one. In this case I would consider code like this:
class MyClass2
{
MyClass2() {};
static auto& InternalGetInstance()
{
static std::shared_ptr<MyClass2> instance { new MyClass2 };
return instance;
}
public:
static std::shared_ptr<MyClass2> GetInstance()
{
return std::atomic_load(std::addressof(InternalGetInstance()));
}
static void reset() {
std::atomic_store(std::addressof(InternalGetInstance()),
std::shared_ptr<MyClass2>(new MyClass2));
}
};
However, in the end, it is my view that 'staticness' of a class should be an implementation detail, and unimportant to the user of the class:
#include <memory>
#include <utility>
class MyClass
{
// internal mechanics
struct Impl {
auto doSomething() {
// actual implementation here.
}
};
// getImpl now becomes the customisation point if you wish to change the
// bahviour of the class later
static Impl& getImpl() {
static auto impl = Impl();
return impl;
}
// use value semantics - it makes for more readable and loosely-coupled code
public:
MyClass() {}
// public methods defer to internal implementation
auto doSomething() {
return getImpl().doSomething();
}
};
int main() {
// note: just create objects
auto mc = MyClass();
mc.doSomething();
// now we can pass the singleton as an object. Other functions don't even
// need to know it's a singlton:
extern void somethingElse(MyClass mc);
somethingElse(mc);
}
void somethingElse(MyClass mc)
{
}
Please take VTT's comment seriously.
To your question:
My question is: why new can invoke a private constructor but make_shared not?
The new is actually used within a lambda in a member-function; Well, A lambda defines a local-class, and C++ standards permits a local-class within a member-function to access everything the member-function can access. And its trivial to remember that member functions can access privates..
std::make_shared has no access to the privates of MyClass. It's outside the scope of MyClass
Example:
class X{
X(){};
public:
static X* create(){ // This member-function can access private functions and ctors/dtor
auto lm = [](){ // This lambda inherits the same access of enclosing member-function
return new X();
};
return lm();
}
};
int main(){
auto x = X::create(); //valid;
auto y = new X(); //invalid;
}
You should use Meyers singleton instead. You should ensure that your compiler supports C++11 magic static before.

creating singleton object with shared pointer [duplicate]

I have a singleton class with a private constructor. In the static factory method I do the following:
shared_ptr<MyClass> MyClass::GetInstance()
{
static once_flag onceFlag;
call_once(onceFlag, []() {
if (_instance == nullptr)
_instance.reset(new MyClass());
});
return _instance;
}
If I use
_instance = make_shared<MyClass>();
the code does not compile. My question is: why new can invoke a private constructor but make_shared not?
As mentioned, std::make_shared or its component parts don't have access to private members.
the call_once and once_flag are un-necessary. They are implicit in c++11 static initialisation,
You normally would not want to expose the shared pointer.
class MyClass
{
MyClass() {}
public:
static MyClass& GetInstance()
{
static auto instance = MyClass();
return instance;
}
};
However, there is one case I can imagine where you would want to expose a shared pointer to the impl - this is in the case where the class can choose to 'break off' or 'reset' the impl to a new one. In this case I would consider code like this:
class MyClass2
{
MyClass2() {};
static auto& InternalGetInstance()
{
static std::shared_ptr<MyClass2> instance { new MyClass2 };
return instance;
}
public:
static std::shared_ptr<MyClass2> GetInstance()
{
return std::atomic_load(std::addressof(InternalGetInstance()));
}
static void reset() {
std::atomic_store(std::addressof(InternalGetInstance()),
std::shared_ptr<MyClass2>(new MyClass2));
}
};
However, in the end, it is my view that 'staticness' of a class should be an implementation detail, and unimportant to the user of the class:
#include <memory>
#include <utility>
class MyClass
{
// internal mechanics
struct Impl {
auto doSomething() {
// actual implementation here.
}
};
// getImpl now becomes the customisation point if you wish to change the
// bahviour of the class later
static Impl& getImpl() {
static auto impl = Impl();
return impl;
}
// use value semantics - it makes for more readable and loosely-coupled code
public:
MyClass() {}
// public methods defer to internal implementation
auto doSomething() {
return getImpl().doSomething();
}
};
int main() {
// note: just create objects
auto mc = MyClass();
mc.doSomething();
// now we can pass the singleton as an object. Other functions don't even
// need to know it's a singlton:
extern void somethingElse(MyClass mc);
somethingElse(mc);
}
void somethingElse(MyClass mc)
{
}
Please take VTT's comment seriously.
To your question:
My question is: why new can invoke a private constructor but make_shared not?
The new is actually used within a lambda in a member-function; Well, A lambda defines a local-class, and C++ standards permits a local-class within a member-function to access everything the member-function can access. And its trivial to remember that member functions can access privates..
std::make_shared has no access to the privates of MyClass. It's outside the scope of MyClass
Example:
class X{
X(){};
public:
static X* create(){ // This member-function can access private functions and ctors/dtor
auto lm = [](){ // This lambda inherits the same access of enclosing member-function
return new X();
};
return lm();
}
};
int main(){
auto x = X::create(); //valid;
auto y = new X(); //invalid;
}
You should use Meyers singleton instead. You should ensure that your compiler supports C++11 magic static before.

Singleton Design Pattern - Explicitly stating a Constructor outside the class

I was trying to implement singleton pattern with an assumption of just using a private constructor, private instance of the class and a public static method to return the instance. But I encountered an error to the following code in Visual Studio
// Singleton Invoice
#include <iostream>
using namespace std;
class Singleton {
public:
//Public Static method with return type of Class to access that instance.
static Singleton* getInstance();
private:
//Private Constructor
Singleton();
//Private Static Instance of Class
static Singleton* objSingleton;
};
Singleton* Singleton::objSingleton = NULL;
Singleton* Singleton::getInstance() {
if (objSingleton == NULL) {
//Lazy Instantiation: if the instance is not needed it will never be created
objSingleton = new Singleton();
cout << "Object is created" << endl;
}
else
{
cout << "Object is already created" << endl;
}
return objSingleton;
}
int main() {
Singleton::getInstance();
Singleton::getInstance();
Singleton::getInstance();
return 0;
}
The error as :
LNK2019 unresolved external symbol "private: __thiscall Singleton::Singleton(void)" (??0Singleton##AAE#XZ) referenced in function "public: static class Singleton * __cdecl Singleton::getInstance(void)" (?getInstance#Singleton##SAPAV1#XZ)
Then I resolved the error but rewriting the constructor outside the class
Singleton::Singleton() {
}
I would like to know the cause for the error and why a constructor needs to be explicitly written outside the class.
In the class the constructor was only declared, not defined. A definition includes a function body. It doesn't matter much whether you define it inline in the class, or outside the class (as you did), but one little difference is that with a definition in the class it's implicitly inline.
In other news:
Singletons improve on global variables by avoiding e.g. the static initialization order fiasco, but have the same problems with respect to invisible lines of communication and side effects. Best avoided.
If you don't need a singleton to persist after a corresponding global variable would be destroyed, then just use a simple Meyers' singleton.
Here's a Meyers' singleton:
class Foo
{
private:
Foo() {}
public:
static auto instance()
-> Foo&
{
static Foo the_instance;
return the_instance;
}
};
The default constructor needs a body:
You could change
Singleton();
to
Singleton(){};
inside the class and it should work.
With C++11 we can use the 'default' specifier to instruct the compiler to create the default implementation of the constructor.
Refer to the below code snippet which is working for me:
class Singleton
{
static Singleton* m_instance;
Singleton()=default; /* Note the use of default specifier here*/
public:
Singleton(const Singleton&) = delete;
Singleton& operator=(const Singleton&) = delete;
static Singleton* getInstance()
{
if(!m_instance){m_instance= new Singleton();}
return m_instance;
}
};
In an evolution of the Meyer's singleton, I prefer the value-semantic singleton, for reasons mentioned in the code below:
class singleton
{
// private implementation
struct impl {
void do_something() { }
};
// private decision as to whether it's really a singleton and what its lifetime
// will be
static impl& instance() { static impl _impl; return _impl; }
public:
// public interface defers to private lifetime policy and implementation
void do_something() { instance().do_something(); }
};
void something(singleton s)
{
s.do_something();
}
int main()
{
// we can now pass singletons by value which gives many benefits:
// 1) if they later become non-singletons, the code does not have to change
// 2) the implementation can be private so better encapsulation
// 3) we can use them in ADL more effectively
auto x = singleton();
something(x);
something(singleton());
}
Pagadala is right. The constructor definition is missing hence the linker error

Singleton with multithreads

This question was asked in an interview. The first part was to write the singleton class:
class Singleton
{
static Singleton *singletonInstance;
Singleton() {}
public:
static Singleton* getSingletonInstance()
{
if(singletonInstance == null)
{
singletonInstance = new Singleton();
}
return singletonInstance;
}
};
Then I was asked how to handle this getSingletonInstance() in a multithreaded situation. I wasn't really sure, but I modified as:
class Singleton
{
static Singleton *singletonInstance;
Singleton() {}
static mutex m_;
public:
static Singleton* getSingletonInstance()
{
m_pend();
if(singletonInstance == null)
{
singletonInstance = new Singleton();
}
return singletonInstance;
}
static void releaseSingleton()
{
m_post();
}
};
Then I was told that although a mutex is required, pending and posting a mutex is not efficient as it takes time. And there is a better way to handle to this situation.
Does anybody know a better and more efficient way to handle the singleton class in a multithreaded situation?
In C++11, the following is guaranteed to perform thread-safe initialisation:
static Singleton* getSingletonInstance()
{
static Singleton instance;
return &instance;
}
In C++03, a common approach was to use double-checked locking; checking a flag (or the pointer itself) to see if the object might be uninitialised, and only locking the mutex if it might be. This requires some kind of non-standard way of atomically reading the pointer (or an associated boolean flag); many implementations incorrectly use a plain pointer or bool, with no guarantee that changes on one processor are visible on others. The code might look something like this, although I've almost certainly got something wrong:
static Singleton* getSingletonInstance()
{
if (!atomic_read(singletonInstance)) {
mutex_lock lock(mutex);
if (!atomic_read(singletonInstance)) {
atomic_write(singletonInstance, new Singleton);
}
}
return singletonInstance;
}
This is quite tricky to get right, so I suggest that you don't bother. In C++11, you could use standard atomic and mutex types, if for some reason you want to keep the dynamic allocation of you example.
Note that I'm only talking about synchronised initialisation, not synchronised access to the object (which your version provides by locking the mutex in the accessor, and releasing it later via a separate function). If you need the lock to safely access the object itself, then you obviously can't avoid locking on every access.
As #piokuc suggested, you can also use a once function here. If you have C++11:
#include <mutex>
static void init_singleton() {
singletonInstance = new Singleton;
}
static std::once_flag singleton_flag;
Singleton* getSingletonInstance() {
std::call_once(singleton_flag, init_singleton);
return singletonInstance;
}
And, yes, this will work sensibly if the new Singleton throws an exception.
If you have C++11 you can make singletonInstance an atomic variable, then use a double-checked lock:
if (singletonInstance == NULL) {
lock the mutex
if (singletonInstance == NULL) {
singletonInstance = new Singleton;
}
unlock the mutex
}
return singletonInstance;
You should actually lock the singleton, and not the instance. If the instance requires locking, that should be handled by the caller (or perhaps by the instance itself, depending on what kind of an interface it exposes)
Update sample code:
#include <mutex>
class Singleton
{
static Singleton *singletonInstance;
Singleton() {}
static std::mutex m_;
public:
static Singleton* getSingletonInstance()
{
std::lock_guard<std::mutex> lock(m_);
if(singletonInstance == nullptr)
{
singletonInstance = new Singleton();
}
return singletonInstance;
}
}
If you use POSIX threads you can use pthread_once_t and pthread_key_t stuff, this way you can avoid using mutexes altogether. For example:
template<class T> class ThreadSingleton : private NonCopyable {
public:
ThreadSingleton();
~ThreadSingleton();
static T& instance();
private:
ThreadSingleton( const ThreadSingleton& );
const ThreadSingleton& operator=( const ThreadSingleton& )
static pthread_once_t once_;
static pthread_key_t key_;
static void init(void);
static void cleanUp(void*);
};
And implementation:
template<class T> pthread_once_t ThreadSingleton<T>::once_ = PTHREAD_ONCE_INIT;
template<class T> pthread_key_t ThreadSingleton<T>::key_;
template<class T>
T& ThreadSingleton<T>::instance()
{
pthread_once(&once_,init);
T* value = (T*)pthread_getspecific(key_);
if(!value)
{
value = new T();
pthread_setspecific(key_,value);
}
return *value;
}
template<class T> void ThreadSingleton<T>::cleanUp(void* data)
{
delete (T*)data;
pthread_setspecific(key_,0);
}
template<class T> void ThreadSingleton<T>::init()
{
pthread_key_create(&key_,cleanUp);
}

C++: Templates and the singleton pattern

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;