890

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?

Artem Barger
  • 40,769
  • 9
  • 59
  • 81
  • freeing some resources, but for it doesn't seems to ever happen. – Artem Barger Jun 17 '09 at 16:10
  • See here for how to define a singelton that is atumatically destroyed. http://stackoverflow.com/questions/86582/singleton-how-should-it-be-used – Martin York Jun 17 '09 at 16:20
  • 19
    See also: http://stackoverflow.com/questions/211237/c-static-variables-initialisation-order/211307#211307 and http://stackoverflow.com/questions/270947/can-any-one-provide-me-a-sample-of-singleton-in-c/271104#271104 and http://stackoverflow.com/questions/246564/what-is-the-lifetime-of-a-static-variable-in-a-c-function and http://stackoverflow.com/questions/449436/singleton-instance-declared-as-static-variable-of-getinstance-method/449823#449823 and http://stackoverflow.com/questions/335369/finding-c-static-initialization-order-problems/335746#335746 – Martin York Jun 17 '09 at 16:43
  • 13
    You'll find a great discussion of how to implement a singleton, along with thread-safety in C++ in this paper. http://www.aristeia.com/Papers/DDJ%5FJul%5FAug%5F2004%5Frevised.pdf –  Oct 30 '09 at 11:34
  • 116
    @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. – derekerdmann Jul 28 '11 at 20:10
  • 2
    @derekerdmann: A singleton is a glorified global variable. They are a good fit for your design whenever a global variable would be a good fit. When was that again? – sbi Jul 28 '11 at 23:34
  • 4
    @sbi - Try working with JNI, bridging between Java and C++. Since the JNI methods are static, interfacing with an existing C++ object hierarchy sometimes calls for a Singleton. Design is not a good place for holy wars. – derekerdmann Jul 29 '11 at 13:09
  • 13
    @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 '11 at 13:26
  • 18
    @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 '11 at 22:21
  • 3
    @jwd: Well, in hindsight, "as little as possible" seems to weak, and I rather stand by "They are a good fit for your design whenever a global variable would be a good fit." Singletons are global variables. The advice for global variables has already been "Don't use them!" when I started programming in the 80ies, and it has never changed. – sbi Oct 17 '11 at 22:38
  • 2
    @sbi When you have a class that starts a device which puts a lock on it upon construction, a singleton is a very good way to ensure that only one instance of the said device interaction class is created. Singletons are not bad. – Patrick.SE Apr 06 '12 at 14:15
  • 2
    @Pat: When you have an `A` that does `B` to a `C`, which in turn does `D` upon `D`... In such complex scenarios almost everything you shouldn't normally do might be the lesser evil to deal with the situation. But after two decades in the industry I have come to the conclusion that such scenarios are vastly more common in discussions than they are in reality. (Granted, you might have made your comment because you _have_ encountered such a situation. But for one, I might have seen other, IMO better, ways to deal with it. And, also, it took half a year on SO until someone came by who has.) – sbi Apr 06 '12 at 19:12
  • 1
    The Singleton design pattern is used to ensure an application never contains more than a single instance of a given type. It is often considered to be an antipattern http://deviq.com/singleton/ – NoWar Aug 30 '16 at 17:57
  • 1
    @DmitryBoyko it's also frequently a misnomer in that it's used where the application CAN contain multiple instances. E.g. in Java a singleton is only unique PER CLASSLOADER, which can lead to "interesting" complications when applications don't account for there being multiple classloaders in play. Other languages no doubt have similar loopholes. What about having 2 processes generating a singleton instance each and then sending them serialised to each other over a pipe for example :) – jwenting Oct 14 '21 at 11:25

24 Answers24

1379

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

ShadowRanger
  • 143,180
  • 12
  • 188
  • 271
Martin York
  • 257,169
  • 86
  • 333
  • 562
  • 2
    @fnieto: Thanks. What I was trying to imply with the constructor S() should be declared private. As singeltons will have other members (otherwise why have a singelton) that need to be initialized (note there is __not__ a Don't implement), so when you do declarea a constructor it will need to be private. – Martin York Oct 19 '09 at 16:55
  • 32
    Good answer. But should note that this is not thread-safe http://stackoverflow.com/questions/1661529/is-meyers-implementation-of-singleton-pattern-thread-safe – Varuna Dec 25 '09 at 08:28
  • 3
    Already noted above in: http://stackoverflow.com/questions/449436/singleton-instance-declared-as-static-variable-of-getinstance-method/449823#449823 – Martin York Dec 25 '09 at 09:44
  • 3
    §6.7 [stmt.dcl] p4 `If control enters the declaration concurrently while the variable is being initialized, the concurrent execution shall wait for completion of the initialization.` – Martin York Jul 29 '12 at 20:50
  • 1
    The trouble with this method is that it is almost indeterminate when the instance gets destroyed, hence you may easily end up with a dangling reference. I would not recommend this method. – Maxim Egorushkin May 20 '13 at 11:09
  • 6
    @MaximYegorushkin: When this is destroyed is **very well defined** (there is no ambiguity). See: http://stackoverflow.com/questions/246564/what-is-the-lifetime-of-a-static-variable-in-a-c-function – Martin York May 20 '13 at 20:39
  • @LokiAstari technically it is well defined by the standard. However, the fact that `getInstance()` returns a reference to an object with a limited lifetime may give the caller false sense of security that the reference is always valid. What irks me most though is the run-time check of the hidden boolean in `getInstance()` guarding the construction of the instance. This is the reason I prefer a plain global object to this pattern, may be with a Schwarz counter to enforce required dynamic initialization/destruction order, just like for `std::cout` and friends, i.e. no overhead on access. – Maxim Egorushkin May 20 '13 at 21:47
  • 1
    @LokiAstari ... and with plain access syntax `std::cout` instead of subjectively ugly `std::ostream::get_cout()`. – Maxim Egorushkin May 20 '13 at 21:48
  • 7
    `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 http://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. – Martin York May 20 '13 at 23:07
  • is there any issue in the below method for accessing the instance? S *s=s->getInstance(); //I will modify the getInstance() so no compilation error and I will be able to get the instance here. But my question is this implementation for accessing the instance is correct? – uss Nov 20 '13 at 09:49
  • @sree **DON'T** do that. Returning pointers is a **big** problem. Use the design above. – Martin York Nov 20 '13 at 15:48
  • 1
    Okay Thank you Loki Astari, will use the above design only. But I don't have much clarity on the statement "Returning pointers is a big problem" . Please explain. – uss Dec 06 '13 at 10:28
  • @sree: Who ownes the pointer you are returning? Which leads to the question who should delete it. Which also adds the question when should I delete it (am I sure that I am the last user). In modern C++ it is unusual to see pointers being passed around as they have no implication of ownership semantics. Normally you pass by reference if you retain ownership (as in the above case) or for dynamically allocated objects you return an appropriate smart pointer to indicate the type of ownership semantics required (look up `std::shared_ptr`). – Martin York Dec 06 '13 at 17:10
  • 1
    Why are {} needed in the private default constructor? It is not necessary and undesired if you want to load some data during initialization of the singleton. – Santosh Tiwari Sep 17 '14 at 15:21
  • 1
    @SantoshTiwari: In the original version I left body out of the constructor (as I did not consider it necessary). The Braces and comment were added by an editor to make the code compilable as shown. – Martin York Sep 17 '14 at 16:31
  • 1
    @kol: Stop messing with the answer you are not adding anything useful. The return type of the assignment operator is not significant. – Martin York Oct 12 '14 at 16:13
  • @LokiAstari I'm sorry. I thought the code is a bit more *readable* if one uses the correct/usual return type for the assignment operator. – kol Oct 12 '14 at 16:26
  • 2
    @kol: `correct return type`. You are conflating terms. You are referring to the default generated assignment operators provided by the compiler. It is **not the correct** one. The correct assignment operator is dependent on situation. And using `void` is more correct in this situation. Note: Any assignment operator prevents the compiler generating a default one. – Martin York Oct 12 '14 at 16:34
  • @LokiAstari Okay, "usual" is the better word, cf. http://en.wikipedia.org/wiki/Assignment_operator_(C%2B%2B)#Return_value_of_overloaded_assignment_operator – kol Oct 12 '14 at 16:41
  • 3
    @kol: No. It is not the usual one. Just because beginners copy and paste code without thinking does not make it the usual one. You should always look at the use case and make sure the assignment operator does what is expected. Copy and pasting code is going to lead you into errors. – Martin York Oct 12 '14 at 16:57
  • 1
    I'd say this implementation is an anti-pattern in C++. You can achieve the desired effect with a global object and [Schwarz Counter](https://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Nifty_Counter) to initialize the object before the first use (like `std::cout` and friends have been initialized for decades). – Maxim Egorushkin Nov 20 '14 at 21:55
  • 1
    @MaximYegorushkin: Sure you can use global objects and `Schwarz Counter` for your global mutable state. But that has different properties (that are applicable to std::cout and family). Like not having lazy initialization. Its a different technique that has uses for different problems. The anti-pattern here is not this implementation but the use of global mutable state. – Martin York Nov 20 '14 at 22:03
  • @LokiAstari Syntax-size, it is `instance.foo()` vs `get_instance().foo()`. Could you elaborate a bit on different properties you refer to please, because initialization-wise, in my eyes, it is no different than when using global objects with Schwarz Counter? – Maxim Egorushkin Nov 20 '14 at 22:10
  • 2
    @MaximYegorushkin: Schwarts counters always initialize the object. The above initializes only on first use. – Martin York Nov 20 '14 at 23:47
  • If you are not going to implement a function, declare it like `S(S const&) = delete;` instead of declaring under private modifier. Makes it more readable. – JohnJohn Jan 27 '15 at 16:28
  • what if I want a custom initialization of the singleton? – brita_ Mar 25 '15 at 13:31
  • @brita_: This is just an example of how to get it working with a static member. In reality this is not how you would do it. You should really combine the Singleton pattern with a creator pattern (such as factory, but any of the creator patterns will do). Because you want to de-couple the creation logic from the retrieval logic. In reality the line above would look more like: `static Singelton& instance = SingetonFactory::create();` In the factory you can have the appropriate functionality and register how you want the object created. – Martin York Mar 25 '15 at 13:47
  • 1
    Any reason why the deleted copy constructor and copy assignment operator are declared as `private` deleted member functions? 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 bahaviour to check accessibility before deleted status. – Schnigges Dec 05 '15 at 11:51
  • Can the `S` constructor (and therefore `getInstance` method) have some parameters? – Stefan Stanković Dec 28 '16 at 13:42
  • 2
    @StefanStanković You can. I would not. The problem here is if it is called from more than one location. The location that calls it first is the one that passes the parameters. All other calls the parameters will get dropped on the floor and ignored. **BUT** This is also why the singelton pattern is a bad idea when used by itself. You should use this pattern in combination with a builder pattern (say factory). Overall the singelton pattern is not a good idea. You should probably think of another way to design your application. – Martin York Dec 28 '16 at 18:43
  • Hopefully, it's also thread safe in C++ '03 mode on compilers that support C++ 11 :) It would be the ugliest optimization ever if they turned thread safety off in this case without the compiler running in C++ 11 mode, but I've seen so many ugly optimizations in the world of C++ that it would honestly not surprise me if they did -.- – yeoman Jan 05 '17 at 19:51
  • Should you make a class `Singleton` and then derive off it everytime you want to make a singleton or should you just use this design pattern in each singleton class? – Post Self Jan 18 '17 at 20:07
  • @kim366: That would be a good question to ask on http://softwareengineering.stackexchange.com/ – Martin York Jan 18 '17 at 20:27
  • Is it okay to overload the parentheses instead of doing `getInstance()`? That would be much shorter, but you'd still see that it's a singleton – Post Self Jan 19 '17 at 18:05
  • 1
    @kim366: These are not the type of questions for comments. These types of questions need the full weight of the community behind them and some though. Ask a proper question and get the community to answer Comments should be reserved for comments only about the displayed code (not how to make it better or alternative techniques). – Martin York Jan 19 '17 at 18:13
  • But when I ask a question about naming and doing stuff a certain way, the question will be taken down immediately for being opinion-based! – Post Self Jan 19 '17 at 18:33
  • 1
    @kim366 If you ask an opinion based question then yes. But asking an opinion based question in comments means you get an opinion based answer by me (nobody else is looking). And I try not not answer opinion based questions anyway as there is no real answer. – Martin York Jan 19 '17 at 18:38
  • I would just like to refer to https://stackoverflow.com/questions/39934890/use-of-deleted-copy-constructor-in-the-singleton since it helps with a particular issue i encountered when using the getInstance method in the wrong way. – pklinken Jun 11 '17 at 09:22
  • I don't understand the code `S(S const&) = delete; void operator=(S const&) = delete;`. Has it already put in the `private`? – 123iamking Jan 11 '18 at 08:00
  • This solution works well when compiled with the application. If I however build it in a dll and call any function that uses getInstance(), the constructor of the class never get's called leading then ultimately to segmentation fault... Any ideas why? I can even step over getInstance() with the debugger, but obviously the constructor is just not called. – Aros Jun 14 '18 at 12:42
  • Is `static S instance;` really instantiated when on first access? I doubt that it is initialized and it's constructor called before main when loading application. Am I wrong? – Karolis Milieška Sep 20 '18 at 13:58
  • 1
    @KarolisMilieška Yes you are wrong. Static storage variables inside function scope are constructed on first use. So the first time the function is called is when it is constructed. Now this can happen before main. If `getInstance()` is called from the constructor of another static storage variable in file scope. – Martin York Sep 20 '18 at 16:30
  • @MartinYork, can you share any C++ standard reference? – Karolis Milieška Sep 21 '18 at 05:42
  • 1
    @KarolisMilieška In `n4727`. Section 9.7 Declaration statement. Paragraph 4 `Dynamic initialization of a **block-scope** variable with **static storage duration** or thread storage duration is performed the first time control passes through its declaration;` – Martin York Sep 21 '18 at 15:35
  • 1
    @KarolisMilieška But I should not have needed to tell you that. You could have written a program in 30 seconds that told you the answer. – Martin York Sep 21 '18 at 15:38
  • How do you know that `instance` isn't instantiated until `getInstance` is called? Is that how static variables work? That would mean that `getInstance` needs to have some hidden variable telling it whether it has been called before. – HelloGoodbye Mar 15 '19 at 08:44
  • @HelloGoodbye Yes that is how static storage function variables work. How it works is implementation defined the standard does not tell you how to make it work it just tells you how the code should work. Now your suggestion of a hidden variable is one technique another is to have two entry points and the entry point defined by indirect call. I am sure there are potential others that I have not thought about. – Martin York Mar 15 '19 at 18:19
  • @HelloGoodbye Its not important. The point I am trying to make is that it does not necessarily mean variable is required. The implementors are allowed to use machine specific constructs to make things happen as long as the behavior is as defined by the standard. This does not mean there is an extra cost in general. You would need to decompile what your compiler generates and look at what it generated to understand the actual implementation does. And knowing this does not give you information about any other implementation. – Martin York Mar 16 '19 at 01:32
  • @MartinYork But how is a program suposed to know whether a static variable should be initialized for a specific call to the function in which it is defined unless it has some memory (i.e. a hidden variable) of whether the variable has already been initialized? If you have some method of solving this without using a hidden variable, I wanna know about it. – HelloGoodbye Mar 17 '19 at 02:44
  • @HelloGoodbye You're missing the point. The compiler implementers are free to use any technique. Just because you (and I mean you in the generic "you" not the specific "you") don't know all the tricks of a compiler engineer does not mean it is not possible. **BUT** using a variable is a very simple and reliable way of doing it; and I would be bet a lot of implementations do it that way. But a lot does not mean all. – Martin York Mar 17 '19 at 03:43
  • @MartinYork I get your point; the C++ specification doesn't say how things should be implemented by the compiler, only what behavior the resulting executable should have. But since you say it's possible to implement this behavior by using two entry points and no hidden variable, and I don't see how it would be possible _without_ using any hidden variable, my curiosity is piqued and I want to know how your method works. So, could you please explain how that would work? (And yeah, I realize I have gone a bit of topic here, but I hope that's okay!) – HelloGoodbye Mar 19 '19 at 16:09
  • @HelloGoodbye I stopped doing compiler work 20 years ago. Both compilers and hardware have moved on since then so my knowledge is way out of date. BUT I worked on a C++ compiler for a SOC chip. Functions with static storage duration objects were implemented with multiple entry points. With some analysis we could usually identify the first caller to a one of these functions so this caller can hit the entry point the forces initialization of the static storage objects. Other calls would then use the other entry point (if you can identify first caller you can fall back to standard method). – Martin York Mar 19 '19 at 18:00
  • 1
    @HelloGoodbye Another system I worked on held on function calls in a table and the call instruction was an index into this table (there was no such thing as a direct call). So initially you can point at the first entry point (which does the initialization of static members and then update the call table so that subsequent calls use the second entry point into the function). – Martin York Mar 19 '19 at 18:13
  • @HelloGoodbye At university for my PhD I wrote a compiler for a DataFlow processor. Here there was no concept of memory. All objects were stored as state that flowed across edges. I have no idea how it was implemented here (somebody else did that part) but since there was no concept of memory or variables you can not the concept of remembering if it was initialized. It is either initialized and flowing across and edge or it did not exist. – Martin York Mar 19 '19 at 18:15
  • @HelloGoodbye Given knowledge of the underlying hardware you can usually find micro optimizations that are unavailable at the language level and so obscure that assembler writers don't use them. But once worked out are relatively easy to add to a compiler (that can quickly validate all pre-conditions at compile time). – Martin York Mar 19 '19 at 18:21
  • @HelloGoodbye: The function call table was part of hardware protection. There were actually multiple call tables. The table being used depended on the state of the hardware. Thus you can prevent/catch calls to illegal subsytems at the hardware level with basically no active checking in the code paths. Thus leading to faster and smaller code. – Martin York Mar 19 '19 at 18:26
  • @MartinYork Wow, that was a thorough explanation, thank you very much! You seem to have a lot of knowledge and experience in this area. Ah, so with the multiple entry points, you basically find out in compile-time which call is the first one—clever; I didn't think of that. And I guess the function call table implicitly keeps some memory of whether that function has been called before? – HelloGoodbye Mar 19 '19 at 23:28
  • @MartinYork About the dataflow processor, since dataflow programming is usually declarative rather than imperative (right?), I'm not sure what the expected behavior of a static variable in a function would be in this case, since the order of the node evaluations—and hence also of the function calls—usually are arbitrary, right? If so, wouldn't static variables make the behavior undefined since it's dependent on the order of the function calls? – HelloGoodbye Mar 19 '19 at 23:34
  • @HelloGoodbye Dataflow programming may be declarative programming style, but Dataflow architecture have instructions. I was using the Manchester dataflow computer. The C was converted to IF1 which was then optimized then converted to a dataflow graph that was implemented directly dataflow instruction set. We had most features implemented when I was there. I was working on optimization for trying to start function before all parameters were available – Martin York Mar 20 '19 at 04:47
  • Martin York, do you see any C++17 modifications on your answer? – uss Jul 17 '19 at 10:18
  • @Ace Why do you need the copy assignment. The whole point is that there is only one so you should not be able to copy it. **BUT** `S& alias = S::getInstance()` should still work as you are getting a reference to a static storage duration object. Note the `static` in `static S instance;` Did you try and compile it? – Martin York Jul 19 '19 at 17:38
  • Yes I did and g++ gives me use of deleted operator= method. I will try confirming it again. – Ace Jul 19 '19 at 17:39
  • I do not need a copy. I only intend to use an alias. – Ace Jul 19 '19 at 17:40
  • @Ace You can't copy it (that's the point). You can **only** use a reference to the original. – Martin York Jul 19 '19 at 17:44
  • Reference to original is all I want. Either as pointer or as alias. – Ace Jul 19 '19 at 17:44
  • 1
    @Ace P.S. using a singelton is probably a bad idea. Most people would consider it an anti-pattern if used in a context without also include a construction pattern. – Martin York Jul 19 '19 at 17:45
  • 1
    @Ace Please don't use pointers in C++ (with the obvious exceptions). That is a worse idea than Singletons – Martin York Jul 19 '19 at 17:46
  • @MartinYork Thanks for responding. It was actually my bad. I was passing the singleton reference as an instance variable to another constructor. Change the constructor arg to reference and all is well. As far as pointers are concerned, I may have to use it since I am making a real time embedded application. Have to minimize unncessary create/copy of struct on stack . – Ace Jul 19 '19 at 18:23
  • 2
    @Ace Prefer reference (alias) over pointer. Then there is no confusion over ownership. Also `std::unique_ptr` has no over head and will help you manage the lifespan of a pointer. – Martin York Jul 19 '19 at 20:10
  • Yes, it's Singleton, but it allows one dangerous operation. 'S* singleton_ptr = &S::getInstance(); delete singleton_ptr;' – Larry Leow Nov 06 '19 at 15:44
  • 1
    @frederic One of the oldest questions on the site. Additional this is a controversial subject as Singletons are a design pattern but also and antipattern. And in my experience usually done incorrectly as they need to be coupled with other builder patterns to be useful. – Martin York Jan 22 '21 at 17:12
  • 1
    why is the `S() {}` needed there? – m4l490n Jul 05 '21 at 15:11
  • 3
    @m4l490n Its not. But it is showing that you should put the constructor of a singleton in the `private` section of the class. This will prevent instances of the class being accidentally constructed. – Martin York Jul 05 '21 at 16:29
  • Would it be possible to replace `S() {}` with `S() = default` ? – luca Jan 08 '22 at 20:42
  • `S` should probably also be declared `final`. – Spencer Apr 13 '22 at 20:03
62

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.

Cătălin Pitiș
  • 14,123
  • 2
  • 39
  • 62
  • 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 '09 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 '09 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 '17 at 14:12
  • What prevents user from assigning this to multiple objects where compiler behind the scenes uses its own copy constructor? – Tony Tannous Jul 15 '19 at 20:46
  • @Tony Nothing prevents copying, you are right. The copy constructor should be deleted. – ebrahim May 23 '21 at 17:24
  • 2
    @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 '21 at 17:24
55

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.

Reed Copsey
  • 554,122
  • 78
  • 1,158
  • 1,373
  • and I was just about to click "Post" as your, almost identical to mine, answer appeared :) – Damir Zekić Jun 17 '09 at 16:07
  • 4
    if delete is never explicitly called on the static Singleton* instance, wouldn't this still technically be considered a memory leak? – Andrew Garrison Jun 17 '09 at 16:10
  • But what I need to do if I've opened some system resources and want to free them, before I finish, as well I want it to happen automatically. On solution, which comes to my head is to somehow adopt use of smart pointers here. – Artem Barger Jun 17 '09 at 16:12
  • Yes, but it's kind of a memory leak by design. This is one reason why many people feel that Singleton's have a code smell - they kind of break the rules on purpose. They're really just a way to encapsulate a global variable a bit more cleanly than a global, but the same arguments against globals are true against Singletons, including non-deterministic cleanup. See my note about extending it with a cleanup - if you called that during your app teardown (ie: deleted the static), you'd call the destructor, and avoid this situation. – Reed Copsey Jun 17 '09 at 16:13
  • 9
    It's not a memory leak anymore than a simple declaration of a global variable. – ilya n. Jun 17 '09 at 16:14
  • You can use RAII idioms to delete the singleton if you really need to. Better, IMHO, is to use the Meyers Singleton pattern described by Cătălin Pitiș. –  Jun 17 '09 at 16:14
  • @ilya n. memory was allocated but wasn't freed that exactly memory leak and it doesn't matter what is the scope of variable. – Artem Barger Jun 17 '09 at 16:15
  • If you want to be freeing the resource, I'm suspicious that singleton might not be the right tool here. Regardless, I'm not seeing why you couldn't make a "destroy()" method that freed the memory and set the pointer to NULL. Ensuing calls to getInstance() will simply reallocate the memory. – jkerian Jun 17 '09 at 16:16
  • @Neil can you please give me a reference? – Artem Barger Jun 17 '09 at 16:17
  • 18
    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 '09 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. – Martin York Jun 17 '09 at 16:34
  • 9
    @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 '09 at 16:53
  • 8
    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. – Steve Jessop Jan 16 '14 at 10:04
  • 1
    @SteveJessop Would you mind providing an example of such a C++ implementation or operating system that does not reclaim resources on program exit? I don't know that I've ever heard of such a thing, and it interests me. Perhaps you're referencing some sort of RTOS? – David Frye Mar 08 '15 at 22:22
  • 3
    @DavidFrye Actually it's a common situation in several domains. For example, Windows Kernel drivers run in a freestanding environment, i.e. resources aren't retrieved on termination. That's also true for pretty much all of the embedded software. – SomeWittyUsername Apr 03 '15 at 07:15
42

@Loki Astari's answer is excellent.

However there are times with multiple static objects where you need to be able to guarantee that the singleton will not be destroyed until all your static objects that use the singleton no longer need it.

In this case std::shared_ptr can be used to keep the singleton alive for all users even when the static destructors are being called at the end of the program:

class Singleton
{
public:
    Singleton(Singleton const&) = delete;
    Singleton& operator=(Singleton const&) = delete;

    static std::shared_ptr<Singleton> instance()
    {
        static std::shared_ptr<Singleton> s{new Singleton};
        return s;
    }

private:
    Singleton() {}
};
Community
  • 1
  • 1
Galik
  • 47,303
  • 4
  • 80
  • 117
  • Could you explain the two lines with `= delete`, as a C# programmer, this syntax looks a bit weird to me. Or could you provide a link where I can read about this exact syntax? – Mohammed Noureldin Oct 31 '20 at 18:48
  • 2
    @MohammedNoureldin By default `C++` will automatically generate functions to make copies of an object. If you want to prevent your objects from being copied you can "delete" those function. So `= delete` tells the compiler not to generate them. – Galik Oct 31 '20 at 20:53
  • Does this achieve the Nifty Counter pattern mentioned in the unfinished faq https://isocpp.org/wiki/faq/ctors#nifty-counter-idiom? – RexYuan Apr 13 '21 at 21:38
  • @RexYuan Yes, I believe so. It will make sure your *singleton object* is not destroyed until after the very last component that needs it has been destroyed first. But you need to make sure that the singleton itself does not require any global static objects during its destruction and as long as you haven't done anything daft like keeping a raw-pointer or a raw reference to its target object outside of the `std::shared_ptr`. – Galik Apr 13 '21 at 22:29
  • 2
    I've started using this approach in maintenance of some overly-complicated (singleton-heavy) legacy software. When I looked into mysterious crashes we had during termination I found there were several singletons holding pointers to other singletons and calling methods on them during destruction, causing a whole static deinitialization order fiasco. Switching to this approach eliminated the use-after-free errors that were occurring when singletons were destroyed out-of-order by the runtime. It really deserves more votes, thank you! – Joseph Riesen Oct 28 '22 at 17:21
  • Already covered keeping the singelton alive as long as needed: https://stackoverflow.com/questions/335369/finding-c-static-initialization-order-problems/335746#335746 – Martin York Apr 26 '23 at 15:47
16

Another non-allocating alternative: create a singleton, say of class C, as you need it:

singleton<C>()

using

template <class X>
X& singleton()
{
    static X x;
    return x;
}

Neither this nor Cătălin's answer is automatically thread-safe in current C++, but will be in C++0x.

James Hopkin
  • 13,797
  • 1
  • 42
  • 71
  • Currently under gcc it is thread safe (and has been for a while). – Martin York Jun 17 '09 at 16:26
  • 16
    The problem with this design is that if used across multiple libraries. Each library has is own copy of the singleton that that library uses. So it is no longer a singleton. – Martin York Jun 17 '09 at 16:27
13

I did not find a CRTP implementation among the answers, so here it is:

template<typename HeirT>
class Singleton
{
public:
    Singleton() = delete;

    Singleton(const Singleton &) = delete;

    Singleton &operator=(const Singleton &) = delete;

    static HeirT &instance()
    {
        static HeirT instance;
        return instance;
    }
};

To use just inherit your class from this, like: class Test : public Singleton<Test>

Yuriy
  • 701
  • 4
  • 18
10

We went over this topic recently in my EECS class. If you want to look at the lecture notes in detail, visit http://umich.edu/~eecs381/lecture/IdiomsDesPattsCreational.pdf. These notes (and quotations I give in this answer) were created by my Professor, David Kieras.

There are two ways that I know to create a Singleton class correctly.

First Way:

Implement it similar to the way you have it in your example. As for destruction, "Singletons usually endure for the length of the program run; most OSs will recover memory and most other resources when a program terminates, so there is an argument for not worrying about this."

However, it is good practice to clean up at program termination. Therefore, you can do this with an auxiliary static SingletonDestructor class and declare that as a friend in your Singleton.

class Singleton {
public:
  static Singleton* get_instance();
  
  // disable copy/move -- this is a Singleton
  Singleton(const Singleton&) = delete;
  Singleton(Singleton&&) = delete;
  Singleton& operator=(const Singleton&) = delete;
  Singleton& operator=(Singleton&&) = delete;

  friend class Singleton_destroyer;

private:
  Singleton();  // no one else can create one
  ~Singleton(); // prevent accidental deletion

  static Singleton* ptr;
};

// auxiliary static object for destroying the memory of Singleton
class Singleton_destroyer {
public:
  ~Singleton_destroyer { delete Singleton::ptr; }
};

// somewhere in code (Singleton.cpp is probably the best place) 
// create a global static Singleton_destroyer object
Singleton_destoyer the_destroyer;

The Singleton_destroyer will be created on program startup, and "when program terminates, all global/static objects are destroyed by the runtime library shutdown code (inserted by the linker), so the_destroyer will be destroyed; its destructor will delete the Singleton, running its destructor."

Second Way

This is called the Meyers Singleton, created by C++ wizard Scott Meyers. Simply define get_instance() differently. Now you can also get rid of the pointer member variable.

// public member function
static Singleton& Singleton::get_instance()
{
  static Singleton s;
  return s;
}

This is neat because the value returned is by reference and you can use . syntax instead of -> to access member variables.

"Compiler automatically builds code that creates 's' first time through the declaration, not thereafter, and then deletes the static object at program termination."

Note also that with the Meyers Singleton you "can get into very difficult situation if objects rely on each other at the time of termination - when does the Singleton disappear relative to other objects? But for simple applications, this works fine."

Tony Bai
  • 396
  • 1
  • 7
  • 13
8

Here is an easy implementation.

#include <Windows.h>
#include <iostream>

using namespace std;


class SingletonClass {

public:
    static SingletonClass* getInstance() {

    return (!m_instanceSingleton) ?
        m_instanceSingleton = new SingletonClass : 
        m_instanceSingleton;
    }

private:
    // private constructor and destructor
    SingletonClass() { cout << "SingletonClass instance created!\n"; }
    ~SingletonClass() {}

    // private copy constructor and assignment operator
    SingletonClass(const SingletonClass&);
    SingletonClass& operator=(const SingletonClass&);

    static SingletonClass *m_instanceSingleton;
};

SingletonClass* SingletonClass::m_instanceSingleton = nullptr;



int main(int argc, const char * argv[]) {

    SingletonClass *singleton;
    singleton = singleton->getInstance();
    cout << singleton << endl;

    // Another object gets the reference of the first object!
    SingletonClass *anotherSingleton;
    anotherSingleton = anotherSingleton->getInstance();
    cout << anotherSingleton << endl;

    Sleep(5000);

    return 0;
}

Only one object created and this object reference is returned each and every time afterwords.

SingletonClass instance created!
00915CB8
00915CB8

Here 00915CB8 is the memory location of singleton Object, same for the duration of the program but (normally!) different each time the program is run.

N.B. This is not a thread safe one.You have to ensure thread safety.

LastBlow
  • 617
  • 9
  • 16
Tunvir Rahman Tusher
  • 6,421
  • 2
  • 37
  • 32
8

Has anyone mentioned std::call_once and std::once_flag? Most other approaches - including double checked locking - are broken.

One major problem in singleton pattern implementation is safe initialization. The only safe way is to guard the initialization sequence with synchronizing barriers. But those barriers themselves need to be safely initiated. std::once_flag is the mechanism to get guaranteed safe initialization.

Red.Wave
  • 2,790
  • 11
  • 17
7

The solution in the accepted answer has a significant drawback - the destructor for the singleton is called after the control leaves the main() function. There may be problems really, when some dependent objects are allocated inside main.

I met this problem, when trying to introduce a Singleton in the Qt application. I decided, that all my setup dialogs must be Singletons, and adopted the pattern above. Unfortunately, Qt's main class QApplication was allocated on stack in the main function, and Qt forbids creating/destroying dialogs when no application object is available.

That is why I prefer heap-allocated singletons. I provide an explicit init() and term() methods for all the singletons and call them inside main. Thus I have a full control over the order of singletons creation/destruction, and also I guarantee that singletons will be created, no matter whether someone called getInstance() or not.

HugoTeixeira
  • 4,674
  • 3
  • 22
  • 32
SadSido
  • 2,511
  • 22
  • 36
  • 4
    If you are referring to the currently accepted answer you first statement is wrong. The destructor is not called until all static storage duration objects are destroyed. – Martin York Oct 12 '12 at 16:40
5

If you want to allocate the object in heap, why don't use a unique pointer. Memory will also be deallocated since we are using a unique pointer.

class S
{
    public:
        static S& getInstance()
        {
            if( m_s.get() == 0 )
            {
              m_s.reset( new S() );
            }
            return *m_s;
        }

    private:
        static std::unique_ptr<S> m_s;

        S();
        S(S const&);            // Don't Implement
        void operator=(S const&); // Don't implement
};

std::unique_ptr<S> S::m_s(0);
Nicolas Holthaus
  • 7,763
  • 4
  • 42
  • 97
riderchap
  • 667
  • 2
  • 11
  • 19
  • 3
    Deprecated in c++11. unique_ptr is recommended instead. http://www.cplusplus.com/reference/memory/auto_ptr/ http://www.cplusplus.com/reference/memory/unique_ptr/ – Andrew Sep 24 '16 at 05:19
  • 3
    This isn't thread safe. Better to make `m_s` a local `static` of `getInstance()`and initialize it immediately without a test. – Galik Apr 12 '17 at 12:28
  • Comparing `m_s.get()` with `nullptr` would be better than with `0`. – ChrisZZ Nov 20 '21 at 17:17
4

C++11 Thread safe implementation:

 #include <iostream>
 #include <thread>


 class Singleton
 {
     private:
         static Singleton * _instance;
         static std::mutex mutex_;

     protected:
         Singleton(const std::string value): value_(value)
         {
         }
         ~Singleton() {}
         std::string value_;

     public:
         /**
          * Singletons should not be cloneable.
          */
         Singleton(Singleton &other) = delete;
         /**
          * Singletons should not be assignable.
          */
         void operator=(const Singleton &) = delete;

         //static Singleton *GetInstance(const std::string& value);
         static Singleton *GetInstance(const std::string& value)
         {
             if (_instance == nullptr)
             {
                 std::lock_guard<std::mutex> lock(mutex_);
                 if (_instance == nullptr)
                 {
                     _instance = new Singleton(value);
                 }
             }
             return _instance;
         }

         std::string value() const{
             return value_;
         }
 };

 /**
  * Static methods should be defined outside the class.
  */
 Singleton* Singleton::_instance = nullptr;
 std::mutex Singleton::mutex_;


 void ThreadFoo(){
     std::this_thread::sleep_for(std::chrono::milliseconds(10));
     Singleton* singleton = Singleton::GetInstance("FOO");
     std::cout << singleton->value() << "\n";
 }

 void ThreadBar(){
     std::this_thread::sleep_for(std::chrono::milliseconds(1000));
     Singleton* singleton = Singleton::GetInstance("BAR");
     std::cout << singleton->value() << "\n";
 }

 int main()
 {
     std::cout <<"If you see the same value, then singleton was reused (yay!\n" <<
                 "If you see different values, then 2 singletons were created (booo!!)\n\n" <<
                 "RESULT:\n";
     std::thread t1(ThreadFoo);
     std::thread t2(ThreadBar);
     t1.join();
     t2.join();
     std::cout << "Complete!" << std::endl;

     return 0;
 }
Milind Deore
  • 2,887
  • 5
  • 25
  • 40
  • 4
    A simple local static function variable is thread safe if your C++ compiler is standards compliant. No need for all the mutex magic. It does mean that static initializers can cause deadlock so one needs to be careful, but so does your suggested code here. – ozzee May 18 '21 at 23:52
  • The problem with local static variable is that it is not unit-testable. – uuu777 Jun 15 '23 at 12:22
3

It is indeed probably allocated from the heap, but without the sources there is no way of knowing.

The typical implementation (taken from some code I have in emacs already) would be:

Singleton * Singleton::getInstance() {
    if (!instance) {
        instance = new Singleton();
    };
    return instance;
};

...and rely on the program going out of scope to clean up afterwards.

If you work on a platform where cleanup must be done manually, I'd probably add a manual cleanup routine.

Another issue with doing it this way is that it isn't thread-safe. In a multithreaded environment, two threads could get through the "if" before either has a chance to allocate the new instance (so both would). This still isn't too big of a deal if you are relying on program termination to clean up anyway.

T.E.D.
  • 44,016
  • 10
  • 73
  • 134
  • you can deduce, since you can see that instance variable is a pointer to the class instance. – Artem Barger Jun 17 '09 at 16:18
  • 3
    There is no need to dynamically allocate the singleton. In fact this is a bad idea as there is not way to automatically de-allocate using the above design. Let it fall out of scope is does not call destructors and is just lazy. – Martin York Jun 17 '09 at 16:25
  • You can automatically deallocate using the atexit function. That's what we do (not saying it's a good idea) – Joe Jun 17 '09 at 20:15
2

Here is a mockable singleton using CRTP. It relies on a little helper to enforce a single object at any one time (at most). To enforce a single object over program execution, remove the reset (which we find useful for tests).

A ConcreteSinleton can be implemented like this:

class ConcreteSingleton : public Singleton<ConcreteSingleton>
{
public:
  ConcreteSingleton(const Singleton<ConcreteSingleton>::PrivatePass&)
      : Singleton<StandardPaths>::Singleton{pass}
  {}
  
  // ... concrete interface
  int f() const {return 42;}

};

And then used with

ConcreteSingleton::instance().f();
ricab
  • 2,697
  • 4
  • 23
  • 28
1

This is about object life-time management. Suppose you have more than singletons in your software. And they depend on Logger singleton. During application destruction, suppose another singleton object uses Logger to log its destruction steps. You have to guarantee that Logger should be cleaned up last. Therefore, please also check out this paper: http://www.cs.wustl.edu/~schmidt/PDF/ObjMan.pdf

baris.aydinoz
  • 1,902
  • 2
  • 18
  • 28
1

In addition to the other discussion here, it may be worth noting that you can have global-ness, without limiting usage to one instance. For example, consider the case of reference counting something...

struct Store{
   std::array<Something, 1024> data;
   size_t get(size_t idx){ /* ... */ }
   void incr_ref(size_t idx){ /* ... */}
   void decr_ref(size_t idx){ /* ... */}
};

template<Store* store_p>
struct ItemRef{
   size_t idx;
   auto get(){ return store_p->get(idx); };
   ItemRef() { store_p->incr_ref(idx); };
   ~ItemRef() { store_p->decr_ref(idx); };
};

Store store1_g;
Store store2_g; // we don't restrict the number of global Store instances

Now somewhere inside a function (such as main) you can do:

auto ref1_a = ItemRef<&store1_g>(101);
auto ref2_a = ItemRef<&store2_g>(201); 

The refs don't need to store a pointer back to their respective Store because that information is supplied at compile-time. You also don't have to worry about the Store's lifetime because the compiler requires that it is global. If there is indeed only one instance of Store then there's no overhead in this approach; with more than one instance it's up to the compiler to be clever about code generation. If necessary, the ItemRef class can even be made a friend of Store (you can have templated friends!).

If Store itself is a templated class then things get messier, but it is still possible to use this method, perhaps by implementing a helper class with the following signature:

template <typename Store_t, Store_t* store_p>
struct StoreWrapper{ /* stuff to access store_p, e.g. methods returning 
                       instances of ItemRef<Store_t, store_p>. */ };

The user can now create a StoreWrapper type (and global instance) for each global Store instance, and always access the stores via their wrapper instance (thus forgetting about the gory details of the template parameters needed for using Store).

dan-man
  • 2,949
  • 2
  • 25
  • 44
1

Here is my view on how to do proper singletons (and other non-trivial static objects): https://github.com/alex4747-pub/proper_singleton

Summary:

  1. Use static initialization list to instantiate singletons at the right time: after entering main and before enabling multi-threading
  2. Add minor improvements to make it unit-test friendly.
uuu777
  • 765
  • 4
  • 21
1

I would like to show here another example of a singleton in C++. It makes sense to use template programming. Besides, it makes sense to derive your singleton class from a not copyable and not movabe classes. Here how it looks like in the code:

#include<iostream>
#include<string>

class DoNotCopy
{
protected:
    DoNotCopy(void) = default;
    DoNotCopy(const DoNotCopy&) = delete;
    DoNotCopy& operator=(const DoNotCopy&) = delete;
};

class DoNotMove
{
protected:
    DoNotMove(void) = default;
    DoNotMove(DoNotMove&&) = delete;
    DoNotMove& operator=(DoNotMove&&) = delete;
};

class DoNotCopyMove : public DoNotCopy,
    public DoNotMove
{
protected:
    DoNotCopyMove(void) = default;
};

template<class T>
class Singleton : public DoNotCopyMove
{
public:
    static T& Instance(void)
    {
        static T instance;
        return instance;
    }

protected:
    Singleton(void) = default;
};

class Logger final: public Singleton<Logger>
{
public:
    void log(const std::string& str) { std::cout << str << std::endl; }
};



int main()
{
    Logger::Instance().log("xx");
}

The splitting into NotCopyable and NotMovable clases allows you to define your singleton more specific (sometimes you want to move your single instance).

Andrushenko Alexander
  • 1,839
  • 19
  • 14
1

It restrict instantiation of a class to one object. This is useful when exactly one object is needed to coordinate actions across the system

class Singleton {
private:
    int data;
    static Singleton* instance;
    Singleton();
public:
    static Singleton* getInstance();
};
Singleton* Singleton::instance = 0;
Singleton::Singleton()
{
    this->data = 0;
    cout << "constructor called.." << endl;
}

 

Singleton* Singleton::getInstance() {
    if (!instance) {
        instance = new Singleton();
        return instance;
    }
}
int main() {
    Singleton *s = s->getInstance();
    Singleton *s1 =s1->getInstance();
    }
  • This has two issues. (1) getInstance() isn't thread safe: if multiple threads call getInstance() at the same time then multiple Singleton instances could be constructed meaning you have a memory leak. (2) If instance already exists, getInstance() has no return value, so you have undefined behaviour. – jezza Feb 03 '22 at 15:42
0

My implementation is similar to Galik's. The difference is my implementation allows the shared pointers to clean up allocated memory, as opposed to holding onto the memory until the application is exited and the static pointers are cleaned up.

#pragma once

#include <memory>

template<typename T>
class Singleton
{
private:
  static std::weak_ptr<T> _singleton;
public:
  static std::shared_ptr<T> singleton()
  {
    std::shared_ptr<T> singleton = _singleton.lock();
    if (!singleton) 
    {
      singleton.reset(new T());
      _singleton = singleton;
    }

    return singleton;
  }
};

template<typename T>
std::weak_ptr<T> Singleton<T>::_singleton;
Kevin Marshall
  • 301
  • 3
  • 8
0

Your code is correct, except that you didn't declare the instance pointer outside the class. The inside class declarations of static variables are not considered declarations in C++, however this is allowed in other languages like C# or Java etc.

class Singleton
{
   public:
       static Singleton* getInstance( );
   private:
       Singleton( );
       static Singleton* instance;
};
Singleton* Singleton::instance; //we need to declare outside because static variables are global

You must know that Singleton instance doesn't need to be manually deleted by us. We need a single object of it throughout the whole program, so at the end of program execution, it will be automatically deallocated.

Ali Sajjad
  • 3,589
  • 1
  • 28
  • 38
-1

Simple singleton class, This must be your header class file

#ifndef SC_SINGLETON_CLASS_H
#define SC_SINGLETON_CLASS_H

class SingletonClass
{
    public:
        static SingletonClass* Instance()
        {
           static SingletonClass* instance = new SingletonClass();
           return instance;
        }

        void Relocate(int X, int Y, int Z);

    private:
        SingletonClass();
        ~SingletonClass();
};

#define sSingletonClass SingletonClass::Instance()

#endif

Access your singleton like this:

sSingletonClass->Relocate(1, 2, 5);
Ali Khazaee
  • 317
  • 4
  • 14
-1

The paper that was linked to above describes the shortcoming of double checked locking is that the compiler may allocate the memory for the object and set a pointer to the address of the allocated memory, before the object's constructor has been called. It is quite easy in c++ however to use allocaters to allocate the memory manually, and then use a construct call to initialize the memory. Using this appraoch, the double-checked locking works just fine.

  • 2
    Unfortunately not. This has been discussed in great depth by some of the best C++ developers out there. Double checked locking is broken in C++03. – Martin York Oct 12 '12 at 16:44
-2
#define INS(c) private:void operator=(c const&){};public:static c& I(){static c _instance;return _instance;}

Example:

   class CCtrl
    {
    private:
        CCtrl(void);
        virtual ~CCtrl(void);

    public:
        INS(CCtrl);
Gank
  • 4,507
  • 4
  • 49
  • 45