Categories
c++ design-patterns singleton

C++ Singleton design pattern

858

Recently I’ve bumped into a realization/implementation of the Singleton design pattern for C++. It has looked like this (I have adopted it from the real-life example):

// a lot of methods are omitted here
class Singleton
{
   public:
       static Singleton* getInstance( );
       ~Singleton( );
   private:
       Singleton( );
       static Singleton* instance;
};

From this declaration, I can deduce that the instance field is initiated on the heap. That means there is a memory allocation. What is completely unclear for me is when exactly the memory is going to be deallocated? Or is there a bug and memory leak? It seems like there is a problem with the implementation.

My main question is, how do I implement it in the right way?

15

  • 18

  • 11

    You’ll find a great discussion of how to implement a singleton, along with thread-safety in C++ in this paper. aristeia.com/Papers/DDJ%5FJul%5FAug%5F2004%5Frevised.pdf

    – Matthieu N.

    Oct 30, 2009 at 11:34

  • 115

    @sbi – Only a Sith deals in absolutes. Can the vast majority of problems be solved without Singletons? Absolutely. Do Singletons cause problems of their own? Yes. However, I can’t honestly say that they’re bad, since design is all about considering the tradeoffs and understanding the nuances of your approach.

    Jul 28, 2011 at 20:10

  • 12

    @derekerdmann: I didn’t say you never need a global variable (and when you need one, a Singleton sometimes is better). What I said is that they should be used as little as possible. Glorifying Singleton as a valuable design pattern gives the impression it’s good to use it, rather than that it is a hack, making code hard to understand, hard to maintain, and hard to test. This is why I posted my comment. None of what you said so far contradicted this.

    – sbi

    Jul 29, 2011 at 13:26

  • 15

    @sbi: What you said was “Don’t use them.” Not the much more reasonable “they should be used as little as possible” you later changed to – surely you see the difference.

    – jwd

    Oct 17, 2011 at 22:21

1318

In 2008 I provided a C++98 implementation of the Singleton design pattern that is lazy-evaluated, guaranteed-destruction, not-technically-thread-safe:
Can any one provide me a sample of Singleton in c++?

Here is an updated C++11 implementation of the Singleton design pattern that is lazy-evaluated, correctly-destroyed, and thread-safe.

class S
{
    public:
        static S& getInstance()
        {
            static S    instance; // Guaranteed to be destroyed.
                                  // Instantiated on first use.
            return instance;
        }
    private:
        S() {}                    // Constructor? (the {} brackets) are needed here.

        // C++ 03
        // ========
        // Don't forget to declare these two. You want to make sure they
        // are inaccessible(especially from outside), otherwise, you may accidentally get copies of
        // your singleton appearing.
        S(S const&);              // Don't Implement
        void operator=(S const&); // Don't implement

        // C++ 11
        // =======
        // We can use the better technique of deleting the methods
        // we don't want.
    public:
        S(S const&)               = delete;
        void operator=(S const&)  = delete;

        // Note: Scott Meyers mentions in his Effective Modern
        //       C++ book, that deleted functions should generally
        //       be public as it results in better error messages
        //       due to the compilers behavior to check accessibility
        //       before deleted status
};

See this article about when to use a singleton: (not often)
Singleton: How should it be used

See this two article about initialization order and how to cope:
Static variables initialisation order
Finding C++ static initialization order problems

See this article describing lifetimes:
What is the lifetime of a static variable in a C++ function?

See this article that discusses some threading implications to singletons:
Singleton instance declared as static variable of GetInstance method, is it thread-safe?

See this article that explains why double checked locking will not work on C++:
What are all the common undefined behaviours that a C++ programmer should know about?
Dr Dobbs: C++ and The Perils of Double-Checked Locking: Part I

84

  • 29

    Good answer. But should note that this is not thread-safe stackoverflow.com/questions/1661529/…

    – Varuna

    Dec 25, 2009 at 8:28

  • 3

    Already noted above in: stackoverflow.com/questions/449436/…

    Dec 25, 2009 at 9:44

  • 6

    @zourtney: Many people don’t realize what you just did 🙂

    Jan 4, 2013 at 7:06

  • 5

    @MaximYegorushkin: When this is destroyed is very well defined (there is no ambiguity). See: stackoverflow.com/questions/246564/…

    May 20, 2013 at 20:39

  • 5

    What irks me most though is the run-time check of the hidden boolean in getInstance() That is an assumption on implementation technique. There need be no assumptions about it being alive. see stackoverflow.com/a/335746/14065 You can force a situation so that it is always alive (less overhead than Schwarz counter). Global variables have more issues with initialization order (across compilation units) as you not force an order. The advantage of this model is 1) lazy initialization. 2) Ability to enforce an order (Schwarz helps but is uglier). Yep get_instance() is much uglier.

    May 20, 2013 at 23:07

54

You could avoid memory allocation. There are many variants, all having problems in case of multithreading environment.

I prefer this kind of implementation (actually, it is not correctly said I prefer, because I avoid singletons as much as possible):

class Singleton
{
private:
   Singleton();

public:
   static Singleton& instance()
   {
      static Singleton INSTANCE;
      return INSTANCE;
   }
};

It has no dynamic memory allocation.

6

  • 3

    In some instances, this lazy initialization is not the ideal pattern to follow. One example is if the constructor of the singleton allocates memory from the heap and you wish that allocation to be predictable, for instance in an embedded system or other tightly controlled environment. I prefer, when the Singleton pattern is the best pattern to use, to create the instance as a static member of the class.

    – dma

    Jun 17, 2009 at 17:06

  • 3

    For many larger programs, especially those with dynamic libraries. Any global or static object that’s none primitive can lead to segfaults/crashes upon program exit on many platforms due to order of destruction issues upon libraries unloading. This is one of the reasons many coding conventions (including Google’s) ban the use of non-trivial static and global objects.

    – obecalp

    Jun 17, 2009 at 18:04

  • It seems that the static instance in such implementation has internal linkage, and will have unique and independent copies in different translation unit, which will cause confusing and wrong behavior. But I saw many such implementation, am I missing something?

    – FaceBro

    Feb 25, 2017 at 14:12

  • What prevents user from assigning this to multiple objects where compiler behind the scenes uses its own copy constructor?

    Jul 15, 2019 at 20:46

  • 1

    @FaceBro There are two instances of the keyword static here, but neither of them is problematic from the standpoint of linkage. The first appearance of static is about static member functions, which is nothing to do with linkage. The second appearance of static is about the storage duration of INSTANCE. The object will live in memory for the duration of the program, and it doesn’t matter that you cannot access it by name outside of the TU because you access it via the member function instance, which has external linkage.

    – ebrahim

    May 23, 2021 at 17:24


52

Being a Singleton, you usually do not want it to be destructed.

It will get torn down and deallocated when the program terminates, which is the normal, desired behavior for a singleton. If you want to be able to explicitly clean it, it’s fairly easy to add a static method to the class that allows you to restore it to a clean state, and have it reallocate next time it’s used, but that’s outside of the scope of a “classic” singleton.

15

  • 8

    It’s not a memory leak anymore than a simple declaration of a global variable.

    – ilya n.

    Jun 17, 2009 at 16:14

  • 17

    To set something straight… “memory leak” concerns vis-a-vis singletons are completely irrelevent. If you have stateful resources in which deconstruction order matters, singletons can be dangerous; but all of the memory is cleanly regained by the operating system on program termination… nullifying this totally academic point in 99.9% of cases. If you want to argue the grammar back and forth of what is and is not a “memory leak”, that’s fine, but realize that it’s a distraction from actual design decisions.

    – jkerian

    Jun 17, 2009 at 16:21

  • 12

    @jkerian: Memory leaks and destruction in the C++ context is not really about the memory leaking. Really it is about resource control. If you leak memory the destroctor is not called and thus any resources associated with the object are not correctly released. Memory is just the simple example we use when teaching programming but there are much more complex resources out there.

    Jun 17, 2009 at 16:34

  • 7

    @Martin I agree with you completely. Even if the only resource is memory, you will still get into trouble trying to find REAL leaks in your program if you have to wade through a list of leaks, filtering out ones that “don’t matter.” It is better to clean these all up so any tool that reports leaks only reports things that ARE a problem.

    – Dolphin

    Jun 17, 2009 at 16:53

  • 7

    It’s vaguely worth considering that there exist C++ implementations (potentially even hosted ones) in which the “OS” does not recover all resources when your program exits, but which do have some concept of “running your program again” which gives you a fresh set of globals and static locals. On such systems an unfreed singleton is a genuine leak by any sensible definition: if your program is run enough times it will take down the system. Whether you care about portability to such systems is another matter — as long as you aren’t writing a library you almost certainly don’t.

    Jan 16, 2014 at 10:04