Singleton Design Pattern in C++

I’m sure that by now, you’ve heard about Design Patterns in C++ and probably also about Singleton.

This article covers what a singleton is and possible implementations with some standard uses for it.

For detailed information and if you want to learn more about design patterns, you should check out Modern C++ Design: Generic Programming and Design Patterns Applied by Andrei Alexandrescu (which is one of the co-founders of boost).

What is a Singleton?

The Singleton might be one of the best known design patterns and probably the simplest.

It is a creational design pattern and it ensures that only a single instance of a C++ entity is present in a given program and that instance has only one entry point. Basically, you cannot have 2 or more instances of the same Singleton class in the application. It will be initialized exactly once in the entire application.

The Singleton is mostly used for loggers, for example.

Pros and cons

The Singleton has mostly the same pros and cons as a global variable.

Pros:

  • It is very handy
  • Can get rid of duplicated code

Cons:

  • Breaks modularity
  • Hard to test and/or untestable

There are also some arguments that Singleton is actually an anti pattern because of the cons above and some other reasons.

Naive Singleton implementation

So, implementing a “naive” Singleton is quite easy. Basically, what you have to is to have a static creation method and forbid the creation of it from external sources.

class NaiveSingleton
{
private:
    static NaiveSingleton* singleton_;

    // Instance should not be constructible by external means
    NaiveSingleton() = default;

public:
    // Instance should not be copyable
    NaiveSingleton (const NaiveSingleton&) = delete;
    NaiveSingleton& operator=(const NaiveSingleton&) = delete;

    // Provide a function to retrieve the singleton
    static NaiveSingleton* instance()
    {
        if (singleton_ == nullptr)
            singleton_ = new NaiveSingleton();
        
        return singleton_;
    }

    void doSomething()
    {
        // doSomething here
    }
};

// Static variable should be initialized outside the class
NaiveSingleton* NaiveSingleton::singleton_ = nullptr;

// Usage NaiveSingleton
NaiveSingleton* naiveSingleton = NaiveSingleton::instance();
naiveSingleton->doSomething();

Biggest problem of the “Naive” Singleton is that it is not thread safe. There is no mechanism whatsoever to protect our implementation in case of concurrent access.

One way of doing this, is to add a mutex, but we won’t cover that in this article. It’s pretty simple, just add a std::mutex and lock/unlock it when using the resource(the Singleton instance).

Scott Meyer’s Singleton implementation

This is the proper way of implementing a singleton and it’s also thread safe.

There is a very good explanation given here:

Attributed to Scott Meyers, this singleton pattern exploits three important properties:

1.Static function objects are initialized when control flow hits the function for the first time.

2.The lifetime of function static variables begins the first time the program flow encounters the declaration and ends at program termination.

3.If control enters the declaration concurrently while the variable is being initialized, the concurrent execution shall wait for completion of the initialization.

class SMSingleton
{
private:
	// Instance should not be constructible by external means
    SMSingleton() = default;

public:
	// Instance should not be copyable
    SMSingleton (const SMSingleton&) = delete;
    SMSingleton& operator=(const SMSingleton&) = delete;

    // Provide a function to retrieve the singleton
    static SMSingleton& instance()
    {
    	static SMSingleton inst;
    	return inst;
    }

    void doSomething()
    {
    	// doSomething here
    }
};

// Usage SMSingleton - Scott Meyer's Singleton
SMSingleton& smSingleton = SMSingleton::instance();
smSingleton.doSomething();

Source Code

You can find the full source code on my github here.

I will probably update the repository further with more design patterns in C++, in the future.

You can find information on how to build the project in the README file of the github repository.

1 thought on “Singleton Design Pattern in C++”

  1. Pingback: Observer Design Pattern in C++ - cppdev

Leave a Reply

%d bloggers like this: