C ++ various implementations of one singleton

I usually implement a 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&); } 

I recently came across 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 to make the constructor private (2nd implementation)?

Thanks.

+2
c ++ design-patterns static singleton lazy-initialization
source share
5 answers

I don't need to repeat the good point about the lazy singleton design made in other answers.

Let me add the following:

 public: Singleton(); virtual ~Singleton() {} 

The designer of this class considered it necessary:

  • from this Singleton class, let's say a derived class is called DerSingleton
  • DerSingleton can have instances that can be deleted with a pointer to Singleton (therefore DerSingleton not single)

Any instance of DerSingleton also an instance of Singleton by definition, so it follows that if DerSingleton is instanciated, Singleton not single.

So this design claims two things:

  • this class is singleton
  • This class is not single
+4
source share

There is a difference. In the first case, instance initialized the first time the function is called. In the second case, it is initialized when the program starts.

If you create a public constructor, it is not a singleton , since it can be created by someone

+3
source share

The main difference in behavior will come if you try to use singleton while initializing another namespace level variable or a static member of the class. In the first case, since the actual object is created on demand during the first function call, the behavior during construction will be well defined. In the second case, all bets are disabled, since the relative order of initialization of static objects from different translation units is undefined.

Also note that although the first one is safe during construction, it may not be during destruction. That is, if an object with a static storage duration does not use a singleton during construction, it can be initialized to a singleton instance. The destruction order is canceled from the construction order, and in this particular case a single element will be destroyed in front of another object. If this object uses singleton in its destructor, this will cause undefined behavior.

+3
source share

The second implementation is incorrect . The default constructor must be private. Be that as it may, this is not a singleton per se. Additionally, differences between implementations are mentioned in @Andrew and @Brady's answers.

+1
source share

An important difference between the two is that instantiation in the second example is thread safe.

You are absolutely right, the constructor must be closed.

Here is the question related to this: https://stackoverflow.com/a/316618/

0
source share

All Articles