I am trying to implement a singleton class that has to be used in two different threads, one sets up its member variables and the other one uses them, but the constructor is being called twice so I cannot use the members set in the first thread because they have their default value.
The implementation is quite standard, a static function that returns a reference to a static member in that function, I have tried to return a pointer, create a raw pointer and return it and the constructor always is called twice.
class Singleton
{
public:
static Singleton &getInstance()
{
static Singleton instance;
return instance;
}
// public methods
private:
Singleton();
Singleton(const Singleton &) = delete;
Singleton(Singleton &&) = delete;
Singleton &operator=(const Singleton &) = delete;
Singleton &operator=(Singleton &&) = delete;
// member variables
};
The thread trying to access to the singleton has been created using std::async(std::launch::async, lambda)
I expected that instance's constructor is called just the first time I call this function, but the second time instance has a different memory direction.
The C++11 standard guarantees that static local variables are only created once.
This leaves us with the following options:
Your compiler isn't C++11-compliant. Could be because it's old or
you're using the wrong options.
Your Singleton throws an (uncaught) exception, and the
initialization is attempted again.
Your constructor calls getInstance(), which results in undefined
behavior.
The above assumes you've implemented the Singleton pattern correctly. You could've also just messed up in some way, but I can't tell because you haven't provided the full code.
All the info taken from cppreference on static local variables.
Related
I will demonstrate my question using a Singleton pattern but it is a broader question. Please spare me the "Singletons are evil" lectures.
Version 1 of Singleton
class Singleton
{
public:
static Singleton& getInstance()
{
static Singleton instance; // This becomes a class member in Ver.2
return instance;
}
private:
// Constructor, forbid copy and assign operations etc...
}
Version 2 of Singleton
class Singleton
{
public:
static Singleton& getInstance()
{
return instance;
}
private:
static Singleton instance; // I'm here now!
// Constructor, forbid copy and assign operations etc...
}
I will now explain what I think will be the difference is between the two:
Version 1 instance will only be initialized once the flow of the program reaches the actual definition of instance (i.e some part of the program requests an instance using Singleton::getInstace()). Lazy instantiated in other words.
It will only be destroyed when the program terminates.
Version 2 instance will be initialized at the start of the program, before main() is called. Will also be destroyed only when the program terminates.
First of all, am I correct in the above assumptions?
Second, Is this behavior of initialization universal (say for global variables and functions)?
Last, Are there any other nuances I should be alerted about concerning this?
Thanks!
You are correct.
You should also notice that the 2nd version does not guarantee when will the object be created, only that it will be before the main function is called.
This will cause problems if that singleton depends on other singletons and etc
That is, the first version will give you greater control over your code, initialization order and of course - less bugs :)
I have the following problem. I have a singleton with a getInstance member function that returns an instance. I call this somewhere in code and for some reason VC tries to call the copy constructor. Why is this? How do I fix this?
The header:
class FileSystemEntryCollection {
public:
static FileSystemEntryCollection &getInstance();
private:
FileSystemEntryCollection();
FileSystemEntryCollection(FileSystemEntryCollection const&);
void operator=(FileSystemEntryCollection const&);
}
Source file:
FileSystemEntryCollection &FileSystemEntryCollection::getInstance() {
static FileSystemEntryCollection instance = FileSystemEntryCollection();
return instance;
}
The following line calls the copy constructor:
auto collection = FileSystemEntryCollection::getInstance();
I've tried to leave in the relevant code, let me know if something else is needed.
auto collection = FileSystemEntryCollection::getInstance();
needs to be:
auto& collection = FileSystemEntryCollection::getInstance();
^
auto on its own is never a reference type.
With a different compiler you'll get the same error for the initialization of instance.
static FileSystemEntryCollection instance = FileSystemEntryCollection();
The = here calls for copy construction: formally, the compiler creates a temporary (FileSystemEntryCollection()), and copies that into instance. However, in this situation, compilers are allowed to skip the copy construction and construct the object directly in place. That's what your compiler is doing. But compilers aren't required to do this.
Better:
static FileSystemEntryCollection instance;
which uses the default constructor to create instance.
It calls the copy constructor once inside the source file which constructs the static singleton object.
I usually implement the singleton pattern this way :
class Singleton
{
public:
virtual ~Singleton() {}
static Singleton& GetInstance()
{
static Singleton instance;
return instance;
}
private:
Singleton();
Singleton(const Singleton&);
Singleton& operator=(const Singleton&);
}
Recently, I ran into this implementation, which is slightly different :
class Singleton
{
public:
Singleton();
virtual ~Singleton() {}
static Singleton& GetInstance()
{
return instance;
}
private:
Singleton(const Singleton&);
Singleton& operator=(const Singleton&);
static Singleton instance;
}
Singleton Singleton::instance;
Which implementation is better ?
Isn't it dangerous not to make the constructor private (2nd implementation) ?
Thanks.
There is a difference. In first case instance is initialized on first call of the function. In second case it is initialized when program starts.
If you make a public constructor - It's not a singleton, since it's can be created by anyone
I need not repeat the good point about lazy construction of the singleton made in other answers.
Let me add this:
public:
Singleton();
virtual ~Singleton() {}
The designer of this particular class felt a need to allow:
derivation from this Singleton class, say the derived class is called DerSingleton
DerSingleton can have instances which can be deleted with a pointer to Singleton (so DerSingleton is not a singleton)
Any instance of DerSingleton is also a Singleton instance by definition, so it follows that if DerSingleton is instanciated, Singleton is not a singleton.
So this design asserts two things:
this class is a singleton
this class is not a singleton
The main difference in behavior will come if you try to use the singleton during initialization of another namespace level variable or class static member. In the first case, because the actual object is created on demand during the first function call, the behavior during contruction will be well defined. In the second case, all bets are off, since the relative order of initialization of static objects from different translation units is undefined.
Also note that while the first one is safe during construction, it might not be during destruction. That is, if an object with static storage duration does not use the singleton during construction, it could be initialized before the singleton instance. The order of destruction is reversed from the order of construction, and in this particular case the singleton would be destroyed before the other object. If that object uses the singleton in its destructor, it will cause undefined behavior.
The second implementation is wrong. The default constructor should be private. As it is, it is not a singleton per se. Besides that, the differences between the implementations are mentioned in #Andrew and #Brady answers.
One important difference between the two is that the creation of the instance in the second example is thread-safe.
You're absolutely right though, the constructor should be private.
Here's a related question: https://stackoverflow.com/a/10479084/1158895
I'm experiencing a weird issue in which I need to have a default constructor for my template class to work, but some of the classes I'd like to use with the template cannot have default constructors.
What I mean by some classes cannot have default constructors is they have a const reference field, hence, they must be set in the constructor/initialization list. If I have a default constructor, there is nothing to set these references to.
So, I guess there are two possible solutions to this: Find a way to allow for non-default constructors in the template class sometimes or find a way to set the const reference fields in a default constructor.
How do I resolve this?
Here's my template code:
#pragma once
template<class T>
class Singleton
{
public:
static T* getInstance()
{
if(!instance) instance = new T;
return instance;
}
static void setInstance(T* inst)
{
instance = inst;
}
protected:
Singleton();
~Singleton();
private:
Singleton(Singleton const&);
Singleton& operator=(Singleton const&);
static T* instance;
};
template<class T> T* Singleton<T>::instance = 0;
Here's where I set the const reference (in a .cpp):
InputHandler::InputHandler(const sf::Input& inputObject)
: input(inputObject)
{
And input is defined in the header:
const sf::Input& input;
I have to use a constant reference because of this area of code (in a different file):
const sf::Input& input = window.GetInput();
InputHandler* inputHandler = new InputHandler(input);
Singleton<InputHandler>::setInstance(inputHandler);
GetInput() is not one of my methods, and it must return a const sf::Input&
You're invoking the default constructor in getInstance with:
instance = new T;
What do you expect to happen if someone calls getInstance before setInstance?
If it's an error to call getInstance before setInstance, then getInstance should assert or throw or return NULL if called before instance is set. Just get rid of the new T, and your code will compile.
If it's not an error to call getInstance before setInstance, then you don't really have a singleton. Early callers would receive a default constructed object and later callers would get the one set later. That's two instances and therefore not a singleton.
If you have a reference member, then you cannot (sensibly) make your class default-constructible or assignable, since references must be initialised, and can't be reassigned.
If you need those properties from the class, then you probably want the member to be a pointer, initialised to null by default and assignable later if needed.
You could perhaps have the Singleton constructor set the instance pointer, i.e.
Singleton::Singleton()
{
assert(instance == nullptr);
instance = static_cast<T*>(this);
}
You can then remove the setInstance function from the interface and getInstance can simply return instance.
In response to the comment, I was assuming that classes were being defined like this:
class MyClassThatShouldBeASingleton : public Singleton<MyClassThatShouldBeASingleton>
{
};
Of course, this does mean that you need to explicitly set up such a singleton rather than it instantiating automatically as in the original code. It's not necessarily how you'd want all singletons to work, just one way of solving the problem.
I have a question with singlton.
Where should I declare the static member of the singleton class?
why not working like this
class singleton{
private:
static singleton & m_singleton;
public:
static singleton& get_instance{
return m_singleton;
}
}
but I have to be like this
class singleton{
public:
static singleton& get_instance{
static singleton & m_singleton;
return m_singleton;
}
}
What's the differnece?
I know there is another way to use pointer, but now I am only talking about the case to use an object.
Also another questions, what's the pros/cons to use pointer and reference for singleton ?
Thanks so much!
In the first case, the singleton is constructed (constructor called) when the program initializes, before main() is called. In this case you will also need to define the static variable somewhere in your cpp file.
In the second case the singleton is constructed when the function is first called. Mind you that this implementation is not thread safe since static variable initialization in functions is not thread safe. If two threads call this function for what appears to be the first time, there is a small chance you'll end up with two singletons.
Also notice you have a bug in the second one. You cannot define a reference without an initalization. This
static SomeClass &var;
Does not compile. You need to remove the reference to create an actual instance of the class, not a reference, and then return a reference to it.
If in the second example you define the static variable as a pointer you can avoid the threading problem I mentioned by carefully initializing the pointer. Read more about it in this class article (that talks about Java but the core issue is the same)