320

Edit: From another question I provided an answer that has links to a lot of questions/answers about singletons: More info about singletons here:

So I have read the thread Singletons: good design or a crutch?
And the argument still rages.

I see Singletons as a Design Pattern (good and bad).

The problem with Singleton is not the Pattern but rather the users (sorry everybody). Everybody and their father thinks they can implement one correctly (and from the many interviews I have done, most people can't). Also because everybody thinks they can implement a correct Singleton they abuse the Pattern and use it in situations that are not appropriate (replacing global variables with Singletons!).

So the main questions that need to be answered are:

  • When should you use a Singleton
  • How do you implement a Singleton correctly

My hope for this article is that we can collect together in a single place (rather than having to google and search multiple sites) an authoritative source of when (and then how) to use a Singleton correctly. Also appropriate would be a list of Anti-Usages and common bad implementations explaining why they fail to work and for good implementations their weaknesses.


So get the ball rolling:
I will hold my hand up and say this is what I use but probably has problems.
I like "Scott Myers" handling of the subject in his books "Effective C++"

Good Situations to use Singletons (not many):

  • Logging frameworks
  • Thread recycling pools
/*
 * C++ Singleton
 * Limitation: Single Threaded Design
 * See: http://www.aristeia.com/Papers/DDJ_Jul_Aug_2004_revised.pdf
 *      For problems associated with locking in multi threaded applications
 *
 * Limitation:
 * If you use this Singleton (A) within a destructor of another Singleton (B)
 * This Singleton (A) must be fully constructed before the constructor of (B)
 * is called.
 */
class MySingleton
{
    private:
        // Private Constructor
        MySingleton();
        // Stop the compiler generating methods of copy the object
        MySingleton(MySingleton const& copy);            // Not Implemented
        MySingleton& operator=(MySingleton const& copy); // Not Implemented

    public:
        static MySingleton& getInstance()
        {
            // The only instance
            // Guaranteed to be lazy initialized
            // Guaranteed that it will be destroyed correctly
            static MySingleton instance;
            return instance;
        }
};

OK. Lets get some criticism and other implementations together.
:-)

Community
  • 1
  • 1
Martin York
  • 257,169
  • 86
  • 333
  • 562
  • 39
    What if you later decide you want multiple loggers? Or multiple thread pools? If you only want one logger, then only create one instance and make it global. Singletons are only good if you absolutely NEED there to only ever be one and it NEEDS to be global, IMHO. –  Mar 03 '09 at 11:43
  • 4
    Who said a framework can only have 1 logger instance. One singelton representing Framework. Framwork can then give you specific loggers. – Martin York Mar 04 '09 at 00:32
  • Yea. I would not use a singeltong as a threadpool. Just throwing out ideas to spark answers. – Martin York Mar 04 '09 at 00:32
  • @Dan Singleton that implements strategy pattern. Behavior is abstracted from singleton. Singleton is a single point of entry. Don't have two loggers, have one logger that can decide how to log. You can't only output to one log at one time, no need to have two. – Lee Louviere Jul 29 '11 at 15:30
  • 6
    Xaade: what if you want to log to two files? Or to a database? Or a network socket? Or a GUI widget? Point is, don't add artificial restrictions - there is no need to. How often have you ever accidentally created two for loops instead of just one? If you only want one logger then create only one. –  May 01 '12 at 00:55

24 Answers24

197

Answer:

Use a Singleton if:

  • You need to have one and only one object of a type in system

Do not use a Singleton if:

  • You want to save memory
  • You want to try something new
  • You want to show off how much you know
  • Because everyone else is doing it (See cargo cult programmer in wikipedia)
  • In user interface widgets
  • It is supposed to be a cache
  • In strings
  • In Sessions
  • I can go all day long

How to create the best singleton:

  • The smaller, the better. I am a minimalist
  • Make sure it is thread safe
  • Make sure it is never null
  • Make sure it is created only once
  • Lazy or system initialization? Up to your requirements
  • Sometimes the OS or the JVM creates singletons for you (e.g. in Java every class definition is a singleton)
  • Provide a destructor or somehow figure out how to dispose resources
  • Use little memory
talekeDskobeDa
  • 372
  • 2
  • 13
Javaxpert
  • 2,315
  • 1
  • 13
  • 4
  • 15
    Actually, I think you are not quite correct either. I'd rephrase as: "If you *need* to have one and only one object of a type in system AND you *need* to have global access to it" Emphasis on need is mine - don't do it if its convenient, only if you MUST have it. –  Mar 03 '09 at 11:40
  • 94
    You're wrong too. If you need one and only one object, you create one and only one. If there is no logical way that two instances could ever be accomodated without irreversibly corrupting the application, you should consider making it a singleton. And then there's the other aspect, global access: If you don't need global access to the instance, it shouldn't be a singleton. – jalf Apr 17 '09 at 18:36
  • I thought I knew the singleton pattern from the Managed language world, but then I discovered Alexandrescu's book - "Modern C++ Design: Generic Programming and Design Patterns Applied". It changed everything. It goes into great detail about all these concerns with Singleton in C++, and the buddy OSS project, Loki is my first dependency into any C++ project I work on – CVertex May 01 '09 at 09:06
  • "Lazy or system initialization? Up to your requirements".... In a multi-threaded system, you have to work a bit harder to make lazy-initialisation thread-safe; it's probably not worth the effort. – Disillusioned Jul 26 '10 at 10:32
  • 4
    Closed for modification, open for extension. The problem is that you can't extend a singleton to be a duoton or a tripleton. It's stuck as a singleton. – Lee Louviere Jul 29 '11 at 15:37
  • Why should not a singleton be used if you want to save memory? – enzom83 Apr 15 '13 at 18:04
  • 2
    @enzom83: A capital-S Singleton includes code to ensure its singleness. If you only want one instance, you can lose that code and simply create one instance yourself...giving you the memory savings of a single instance, *plus* the savings from the obviation of singleness-enforcing code -- which also means not sacrificing the ability to create a second instance if ever your requirements change. – cHao Jan 06 '14 at 00:05
  • 3
    Could you clarify the reason to use singleton? The current phrasing is confusing because it roughly reads to me as "use singleton when you need ". When does one need ? (...or is this snarky humour?) – Praxeolitic May 26 '14 at 23:23
  • 6
    "If you need to have one and only one object of a type in system" - "...and never want to mock that object in a unit test." – Cygon Oct 19 '14 at 18:21
  • I would second Cygon, Singletons get abused quickly, the ease of having access to them not only proliferates them as an implementation detail but might grow into an Almighty instance capable of screwing up the entire system! The pain they give is much more than the benefit they offer. Dependency Injection (IOC) is much better way for resolving dependencies which can almost always replace the need for Singletons! Remember your header file should be WYSIWYG, not let some creepy Singleton blow your job by directly injecting side-effects somewhere inside the source file :-) – Arun May 21 '15 at 07:51
  • 3
    I dont see why a singleton must have global scope in order to be a valid usage... – BugShotGG Jan 31 '18 at 17:20
  • What do singletons have to do with thread safety? Any class only needs to be thread safe if it needs to be thread safe. What does being a singleton have anything to do with thread safety? – Adam Freeman Sep 23 '20 at 22:52
86

Singletons give you the ability to combine two bad traits in one class. That's wrong in pretty much every way.

A singleton gives you:

  1. Global access to an object, and
  2. A guarantee that no more than one object of this type can ever be created

Number one is straightforward. Globals are generally bad. We should never make objects globally accessible unless we really need it.

Number two may sound like it makes sense, but let's think about it. When was the last time you **accidentally* created a new object instead of referencing an existing one? Since this is tagged C++, let's use an example from that language. Do you often accidentally write

std::ostream os;
os << "hello world\n";

When you intended to write

std::cout << "hello world\n";

Of course not. We don't need protection against this error, because that kind of error just doesn't happen. If it does, the correct response is to go home and sleep for 12-20 hours and hope you feel better.

If only one object is needed, simply create one instance. If one object should be globally accessible, make it a global. But that doesn't mean it should be impossible to create other instances of it.

The "only one instance is possible" constraint doesn't really protect us against likely bugs. But it does make our code very hard to refactor and maintain. Because quite often we find out later that we did need more than one instance. We do have more than one database, we do have more than one configuration object, we do want several loggers. Our unit tests may want to be able to create and recreate these objects every test, to take a common example.

So a singleton should be used if and only if, we need both the traits it offers: If we need global access (which is rare, because globals are generally discouraged) and we need to prevent anyone from ever creating more than one instance of a class (which sounds to me like a design issue). The only reason I can see for this is if creating two instances would corrupt our application state - probably because the class contains a number of static members or similar silliness. In which case the obvious answer is to fix that class. It shouldn't depend on being the only instance.

If you need global access to an object, make it a global, like std::cout. But don't constrain the number of instances that can be created.

If you absolutely, positively need to constrain the number of instances of a class to just one, and there is no way that creating a second instance can ever be handled safely, then enforce that. But don't make it globally accessible as well.

If you do need both traits, then 1) make it a singleton, and 2) let me know what you need that for, because I'm having a hard time imagining such a case.

Toby Speight
  • 27,591
  • 48
  • 66
  • 103
jalf
  • 243,077
  • 51
  • 345
  • 550
  • Assume, in a single thread, you need access to a specific Database object that is shared by an ORM class heirarchy, a ReportGenerator class, and a DataMaintenance class. While you could pass the database instance into the constructor of every object, this could make the instantiation list really long, and rather unmaintainable. Instead, you could create a SharedDatabase object as a singleton, and pass it around that way. – J. Polfer Jul 14 '09 at 21:04
  • 3
    or you could make it a global, and get only *one* of the downsides of a singleton. With the singleton, you'd simultaneously limit yourself to one instance of that database cllass. Why do that? Or you could look at why you have so many dependencies that the instantiation list becomes "really long". Are they all necessary? Should some of them be delegated out to other components? Perhaps some of them could be packaged together in a struct so we can pass them around as a single argument. There are plenty of solutions, all of them better than singletons. – jalf Jul 14 '09 at 22:08
  • @ jalf - Here's the thing - Do you want multiple instances of a database object? Usually *no*, there is only one database. That is one instance where it is helpful to have a global entity that can only have a single instance. – J. Polfer Jul 15 '09 at 13:10
  • 1
    I don't know. That's the key. I might at some point want another instance of the database class. Is it so hard to imagine that an application connects to more than one database? It doesn't seem so strange to me. But more importantly why paint yourself into a corner? If you suspect you only need one instance, then create one instance and make it global. It's not like you "accidentally" create new databases just because the constructor is public. So create one instance, make it global, and leave it at that. There's just no point in preventing me from creating another instance if I decide to. – jalf Jul 15 '09 at 13:13
  • Perhaps I didn't give a good example. One of my coworkers created a class called SpreaderController in a GUI program, that provided access to various internal spreader controller functions of a spreader controller device on a municipal snow plow truck. In any given snow plow truck, there is always, and guaranteed to only be, one spreader controller device. Also, many different places in this app need access to SpreaderController. The app also has many developers. To keep with the system model, and to prevent other developers from making multiple instances, he made it a Singleton. – J. Polfer Jul 15 '09 at 14:44
  • Another example - telephone switch rack - Assume UK Robotics makes a telephone switch that has an administration unit, a box that governs all other telephone switching circuits in a rack. You really only want, programmatically, one AdministrationUnit class at any one time on a distributed code base through out a rack, and you don't want some silly developer out there making more than one. You could make it a global, and from an OO perspective this is a benefit, but in terms of engineering system design that is a fatal flaw - you won't have multiple administration units in the wild. – J. Polfer Jul 15 '09 at 14:51
  • 6
    Yes, a singleton *might* be justified there. But I think you've just proven my point that it's only necessary in pretty exotic cases. Most software does not deal with snow plowing hardware. But I'm still not convinced. I agree that in your actual application you only want one of these. But what about your unit tests? Each of them should run in isolation, so they should ideally create their own SpreaderController - which is hard to do with a singleton. Finally, why would your coworkers create multiple instances in the first place? Is that a realistic scenario to protect against? – jalf Jul 15 '09 at 14:53
  • 1
    So your claim is that because we sometimes interface with physical devices of which only one exist, the singleton pattern is good *in general*? I stand by my claim. Usually, it is an awful idea. Sometimes, rarely, and working with external devices like snow plows is a good example, you really can only meaningfully have one instance. But those are special cases. I'd say a design pattern has to be applicable to more than snow plows to be considered "good". – jalf Jul 15 '09 at 14:56
  • 3
    And a point you missed is that while your last two examples arguably justify the "only one instance" limitation, they do nothing to justify the "globally accessible" one. Why on Earth should the entire codebase be able to acces your telephone switch's administration unit? The point in a singleton is to give you *both* traits. If you just need one or the other, you shouldn't use a singleton. – jalf Jul 15 '09 at 14:59
  • 2
    @ jalf - My goal was just to give you an example of where Singleton is useful in the wild, since you couldn't imagine any; I guess you don't see to many times to apply it your current line of work. I switched into snow plow programming from business applications solely because it would allow me to use Singleton. :) j/k I do agree with your premise that there are better ways to do these things, you've given me much to think about. Thanks for the discussion! – J. Polfer Jul 15 '09 at 15:58
  • 2
    Using the singleton (**AHEM!**) "pattern" to prevent people from instanting more instances is plain old stupid just to prevent people from accedentally doing so. When I have a local variable foo1 of type Foo in my small function and only want one in the function, I'm not worried that someone is going to create a second Foo varaible foo2 and use that instead of the original one. – Thomas Eding May 12 '11 at 22:54
  • Also, I have my singleton Math object with an assortment of methods, say cos, sin, tan... because "naturally" I never need any other ways of computing them This prevents me from subclassing it for customized versions of these functions (say I want to trade accuracy for speed). Instantiating the original Math object probably is dirt cheap as well because most of it is methods and has no (or very little) state. – Thomas Eding May 12 '11 at 22:57
  • Creating a global just doesn't cut it if the global object is to be used by other global objects. There needs to be some way of guaranteeing that it gets constructed before it gets used, and the "function static variable" singleton implementation is a good way of doing that. (Well, a C++11 program could construct the object into aligned storage somewhere, with some globals in a header which perform reference counting, but many projects are stuck with C++03 or earlier). – Mankarse Mar 09 '12 at 17:47
  • That said, it is quite possible to make a function static object without making the class a singleton. – Mankarse Mar 09 '12 at 17:50
  • @Mankarse: if your globals depend on *other* globals, then you have bigger problems. Your program is supposed to take place inside `main`, not before it. – jalf Mar 09 '12 at 23:00
  • When you are working with other team members on a large project (like I am with a video game) - you know a) people aren't always going to know the full ins and outs of the code right away or ever - so forcing/limiting access is a good thing. And b) in a game engine you very well know you need global access to classes if you want a game running at a reasonable framerate. If you can make a game without global access, that can match the speed, ease, and memory savings using full top down design - you'd be the first (and only) one to do so. It's why Singletons are 'trendy' - because they work. – SinisterRainbow Aug 19 '12 at 21:19
  • @SinisterRainbow Perhaps you could explain to silly old me how "global access" could *possibly* affect your framerate? As for the "forcing/limiting access" point, I have absolutely no clue what you're saying. A singleton does *not* limit access. It does the opposite. It makes the component visible to *everyone* everywhere. It adds dependencies, it makes the code *harder* to understand for team members on a large team who don't know "the full ins and outs of the code". You can sabotage your own code all you want, but please don't pretend that it's a good idea – jalf Aug 19 '12 at 23:51
  • @jalf Game Programming Gems 1, chapter 1.1, page 6, author: James Boer (programmer Arena.net, several games, several books written). You want further examples - check every commerical and free engine available - try CryEngine and UDK source code for two of the top. OOP was made to force good habits, but the fact is it runs slower if you true to be a purist in every case (not to mention time wasted trying), and that doesn't always works when you need speed and flexibility. If you can do better, maybe you should write an article yourself and inform silly old Crytek and Epic Games. – SinisterRainbow Aug 20 '12 at 12:00
  • @jalf I would have put a concrete example but the 'little old me' comment signifies significant ego. Here's another game programmer: Scott Bilas, maybe you've heard of him. Regardless, his explanation is far better than mine would be: http://scottbilas.com/publications/gem-singleton/ – SinisterRainbow Aug 20 '12 at 12:14
  • @SinisterRainbow: No, it signifies that I think you're wrong, and that, at the end of the day, you have *not* provided a concrete example. Feel free to blame it on me, but it doesn't change the facts: your only argument so far has been an appeal to authority. Here's a shocking revelation: there are plenty of sucky game developers out there. And there are plenty of game developers who write needlessly crappy code for no good reason. But none of this answers my question: why would absence of singletons adversely affect framerates? – jalf Aug 20 '12 at 13:57
  • All you have shown is that "there are game developers who use singletons", which I do not disagree with. But your claim was that use of singletons was necessary for performance, which is absurd, because (a) there's no cost associated with *not* using a singleton, and (b) singletons mean shared mutable state which is the single biggest performance *killer* in multithreaded code. And fast games today... are multithreaded. – jalf Aug 20 '12 at 13:59
  • I can't argue against " uses singletons". But I *can* argue against "singletons are necessary for performance" and "singletons make the code easier to understand. Show me why singletons are (a) good, and (b) necessary. Showing me that they are (a) widely used, and (b) that some people believe they're *worth using* is irrelevant and unimportant. Appeals to authority isn't a helpful way to debate. – jalf Aug 20 '12 at 14:00
  • And, honestly, if you read the last part of the Gem article you posted, you'll see that he's talking about 15 year old code (VC5) and that his code suffers from some serious flaws. If that's the kind of code you want to take your design advice from, hey, feel free. But don't be surprised if others might disagree with its quality or value. – jalf Aug 20 '12 at 14:05
  • 1
    Arguing because of an apparent logical fallacy of Appeal to authority is correct. However you miss the point entirely. Every game programmer uses them, and there's a reason why. – SinisterRainbow Aug 20 '12 at 14:08
  • 1
    What’s the point of singletons? First they provide conceptual clarity, as labels are very important. Calling a class a singleton and following a naming convention (such as -Mgr, -Api, Global-, etc.) relates important details about how we intend that class to be used. Singletons also provide notational convenience. Every object in a C++ system must be owned by something. The ownership pattern of these objects depends on the game, but often resembles a multi-level hierarchy, where each higher level owns a set of child objects, each of which in turn may own child objects. Cont: – SinisterRainbow Aug 20 '12 at 14:09
  • 1
    Each object publishes a set of functions to access its children. For example, to get at the TextureMgr instance, you may need to call a sequence of functions such as GetApp()->GetServices()->GetGui()->GetTextureMgr(), where each function returns a pointer to the requested child object. This is inconvenient and not exactly efficient, considering the multiple dereferences. Singletons can solve this problem because they are treated as global objects. – SinisterRainbow Aug 20 '12 at 14:09
  • 1
    Well then why not just use global objects? They are certainly convenient – the TextureMgr object could be accessed through a g_TextureMgr object reference that has been declared with external linkage at global scope (or within a namespace), or perhaps through a function that returns a reference to that object instead. However, the construction and destruction order of global objects is implementation dependent and generally impossible to predict in a portable manner. – SinisterRainbow Aug 20 '12 at 14:10
  • 1
    There are workarounds to all these problems, but what we really want is a way to have the convenience advantage of treating a singleton like a global object, without the inconvenience of losing control over when and where it gets constructed and destroyed." <<--- the last 4 posts are from the scottbilas.com site which you did not read, and further have made provided no better solution for. So, find a way to have the savings of multiple dereferences per frame (could be in the thousands, and of course we're talking about potential cache misses ~= ms delays == affected framerate). – SinisterRainbow Aug 20 '12 at 14:15
39

The problem with singletons is not their implementation. It is that they conflate two different concepts, neither of which is obviously desirable.

1) Singletons provide a global access mechanism to an object. Although they might be marginally more threadsafe or marginally more reliable in languages without a well-defined initialization order, this usage is still the moral equivalent of a global variable. It's a global variable dressed up in some awkward syntax (foo::get_instance() instead of g_foo, say), but it serves the exact same purpose (a single object accessible across the entire program) and has the exact same drawbacks.

2) Singletons prevent multiple instantiations of a class. It's rare, IME, that this kind of feature should be baked into a class. It's normally a much more contextual thing; a lot of the things that are regarded as one-and-only-one are really just happens-to-be-only-one. IMO a more appropriate solution is to just create only one instance--until you realize that you need more than one instance.

DrPizza
  • 17,882
  • 7
  • 41
  • 53
  • 6
    Agreed. Two wrongs may make a right according to some, in the real world. But in programming, mixing two bad ideas does not result in a good one. – jalf Apr 17 '09 at 18:49
29

One thing with patterns: don't generalize. They have all cases when they're useful, and when they fail.

Singleton can be nasty when you have to test the code. You're generally stuck with one instance of the class, and can choose between opening up a door in constructor or some method to reset the state and so on.

Other problem is that the Singleton in fact is nothing more than a global variable in disguise. When you have too much global shared state over your program, things tend to go back, we all know it.

It may make dependency tracking harder. When everything depends on your Singleton, it's harder to change it, split to two, etc. You're generally stuck with it. This also hampers flexibility. Investigate some Dependency Injection framework to try to alleviate this issue.

Paweł Hajdan
  • 18,074
  • 9
  • 49
  • 65
  • 8
    No, a singleton is a lot more than a global variable in disguise. That's what makes it especially bad. It combines the global-ness (which is usually bad) with another concept which is *also* bad (that of not letting the programmer instantiate a class if he decides he needs an instance) They are often *used* as global variables, yes. And then they drag in the other nasty side effect as well, and cripple the codebase. – jalf Apr 17 '09 at 18:51
  • 8
    It should also be noted that singletons don't have to have public accessibility. A singleton can very well be internal to the library and never exposed to the user. So they're not necessarily "global" in that sense. – Steven Evers Apr 17 '09 at 19:15
  • 2
    @jalf Not allowing someone to create more than one instance of a class is not a bad thing. If there is really only ever to be one instance of the class instantiated that enforces the requirement. If someone decides later that they need to create another instance they should refactor it, because it should never have been a singleton in the first place. – William Apr 23 '12 at 18:16
  • @William: once something is made a singleton, it becomes incredibly hard to refactor. Now, can you give me a single reason for why it would ever be a good idea to enforce such a "one instance only" limitation? A **single** example of a situation where it is undoubtedly the right thing to do? – jalf Apr 23 '12 at 18:33
  • @jalf Overall I agree with you, but there are the RARE times it's okay. If you think you need a singleton chances are you don't. There's been times where I had to create and tear down an object several times and inside of that object there needed to be a lot of logging done. I made the logging class a singleton so I wouldn't have to add another object I was creating and tearing down a lot. Not everything is either right or wrong even in programming there are shades of gray. – William Apr 29 '12 at 01:05
  • 2
    @William: and I've had to have multiple loggers from time to time. You're not arguing for a singleton, but for a plain old local. You want to know that *a* logger is always available. That's what a global is for. You do not need to know that *no other logger can ever possibly be instantiated*, which is what a singleton enforces. (try writing unit tests for your logger -- that's a lot easier if you can create and destroy it as needed, and that is not possible with a singleton) – jalf Apr 29 '12 at 09:05
  • Of course you're right, it's rarely black or white. But that's no excuse for sticking to bad ideas. I'll gladly admit that a situation *might* exist where a singleton is warranted. But "I need to know that a globally accessible logger is available" is not such a case – jalf Apr 29 '12 at 09:12
  • By the way, your second sentence is a generalization (which your first sentence warns against). Why do you assume that they **all** have cases where they're useful? :) – jalf Oct 22 '12 at 07:06
14

Singletons basically let you have complex global state in languages which otherwise make it difficult or impossible to have complex global variables.

Java in particular uses singletons as a replacement for global variables, since everything must be contained within a class. The closest it comes to global variables are public static variables, which may be used as if they were global with import static

C++ does have global variables, but the order in which constructors of global class variables are invoked is undefined. As such, a singleton lets you defer the creation of a global variable until the first time that variable is needed.

Languages such as Python and Ruby use singletons very little because you can use global variables within a module instead.

So when is it good/bad to use a singleton? Pretty much exactly when it would be good/bad to use a global variable.

Eli Courtwright
  • 186,300
  • 67
  • 213
  • 256
  • When ever is a global variable "good"? Sometimes they're the best workaround for a problem, but they are never "good". – DevSolar Mar 02 '11 at 13:27
  • 2
    global variable is good when it is used everywhere, and everything can have access to it. A implementation of a single state turing machine can make use of a singleton. – Lee Louviere Jul 29 '11 at 15:33
  • I like the layer of indirection in this answer: "when it would be good/bad to use a global". Both DevSolar and Lee Louviere get the value they agree with even though at answertime it could not have been known who would comment. – Praxeolitic May 26 '14 at 23:35
7
  • How do you implement a Singleton correctly

There's one issue I've never seen mentioned, something I ran into at a previous job. We had C++ singletons that were shared between DLLs, and the usual mechanics of ensuring a single instance of a class just don't work. The problem is that each DLL gets its own set of static variables, along with the EXE. If your get_instance function is inline or part of a static library, each DLL will wind up with its own copy of the "singleton".

The solution is to make sure the singleton code is only defined in one DLL or EXE, or create a singleton manager with those properties to parcel out instances.

Toby Speight
  • 27,591
  • 48
  • 66
  • 103
Mark Ransom
  • 299,747
  • 42
  • 398
  • 622
  • 14
    Yo dawg, I heard you liked Singletons, so I made a Singleton for your Singleton, so you can anti-pattern while you anti-pattern. – Eva Feb 24 '13 at 19:56
  • 1
    @Eva, yeah something like that. I didn't create the problem, I just had to make it work somehow. – Mark Ransom Feb 24 '13 at 22:30
7

Modern C++ Design by Alexandrescu has a thread-safe, inheritable generic singleton.

For my 2p-worth, I think it's important to have defined lifetimes for your singletons (when it's absolutely necessary to use them). I normally don't let the static get() function instantiate anything, and leave set-up and destruction to some dedicated section of the main application. This helps highlight dependencies between singletons - but, as stressed above, it's best to just avoid them if possible.

Toby Speight
  • 27,591
  • 48
  • 66
  • 103
tenpn
  • 4,556
  • 5
  • 43
  • 63
6

As others have noted, major downsides to singletons include the inability to extend them, and losing the power to instantiate more than one instance, e.g. for testing purposes.

Some useful aspects of singletons:

  1. lazy or upfront instantiation
  2. handy for an object which requires setup and/or state

However, you don't have to use a singleton to get these benefits. You can write a normal object that does the work, and then have people access it via a factory (a separate object). The factory can worry about only instantiating one, and reusing it, etc., if need be. Also, if you program to an interface rather than a concrete class, the factory can use strategies, i.e. you can switch in and out various implementations of the interface.

Finally, a factory lends itself to dependency injection technologies like Spring etc.

Toby Speight
  • 27,591
  • 48
  • 66
  • 103
5

The first example isn't thread safe - if two threads call getInstance at the same time, that static is going to be a PITA. Some form of mutex would help.

Rob
  • 76,700
  • 56
  • 158
  • 197
  • Yep that is noted in the comments above: * Limitation: Single Threaded Design * See: http://www.aristeia.com/Papers/DDJ_Jul_Aug_2004_revised.pdf * For problems associated with locking in multi threaded applications – Martin York Sep 17 '08 at 19:22
  • The classic singleton with only getInstance as static method and instance methods for other operations can never be made thread safe. (well unless you make it a single-per-thread-ton using thread local storage...) – Tobi Sep 17 '08 at 19:22
  • even in c++11 or later? – hg_git Sep 05 '16 at 16:42
4

Singletons are handy when you've got a lot code being run when you initialize and object. For example, when you using iBatis when you setup a persistence object it has to read all the configs, parse the maps, make sure its all correct, etc.. before getting to your code.

If you did this every time, performance would be much degraded. Using it in a singleton, you take that hit once and then all subsequent calls don't have to do it.

Brian
  • 4,931
  • 3
  • 32
  • 55
  • The [Prototype Pattern](http://en.wikipedia.org/wiki/Prototype_pattern) does this as well, and it's more flexible. You can also use it when your client will make many instances of your expensive class, but only a limited number of them actually have different state. For example, tetronimos in Tetris. – Eva Feb 24 '13 at 19:52
3

Because a singleton only allows one instance to be created it effectively controls instance replication. for example you'd not need multiple instances of a lookup - a morse lookup map for example, thus wrapping it in a singleton class is apt. And just because you have a single instance of the class does not mean you are also limited on the number of references to that instance. You can queue calls(to avoid threading issues) to the instance and effect changes necessary. Yes, the general form of a singleton is a globally public one, you can certainly modify the design to create a more access restricted singleton. I haven't tired this before but I sure know it is possible. And to all those who commented saying the singleton pattern is utterly evil you should know this: yes it is evil if you do not use it properly or within it confines of effective functionality and predictable behavior: do not GENERALIZE.

gogole
  • 151
  • 1
  • 2
  • 10
3

Most people use singletons when they are trying to make themselves feel good about using a global variable. There are legitimate uses, but most of the time when people use them, the fact that there can only be one instance is just a trivial fact compared to the fact that it's globally accessible.

Brad Barker
  • 2,053
  • 3
  • 17
  • 28
3

The real downfall of Singletons is that they break inheritance. You can't derive a new class to give you extended functionality unless you have access to the code where the Singleton is referenced. So, beyond the fact the the Singleton will make your code tightly coupled (fixable by a Strategy Pattern ... aka Dependency Injection) it will also prevent you from closing off sections of the code from revision (shared libraries).

So even the examples of loggers or thread pools are invalid and should be replaced by Strategies.

ZebZiggle
  • 678
  • 2
  • 9
  • 11
  • Loggers themselves should not be singletons. The general "broadcast" messaging system should be. Loggers themselves are subscribers to the broadcast messages. – CashCow Mar 02 '11 at 12:25
  • Thread-pools should also not be singletons. The general question is would you ever want more than one of them? Yes. When I last used them we had 3 different thread-pools in one application. – CashCow Mar 02 '11 at 12:26
2

Below is the better approach for implementing a thread safe singleton pattern with deallocating the memory in destructor itself. But I think the destructor should be an optional because singleton instance will be automatically destroyed when the program terminates:

#include<iostream>
#include<mutex>

using namespace std;
std::mutex mtx;

class MySingleton{
private:
    static MySingleton * singletonInstance;
    MySingleton();
    ~MySingleton();
public:
    static MySingleton* GetInstance();
    MySingleton(const MySingleton&) = delete;
    const MySingleton& operator=(const MySingleton&) = delete;
    MySingleton(MySingleton&& other) noexcept = delete;
    MySingleton& operator=(MySingleton&& other) noexcept = delete;
};

MySingleton* MySingleton::singletonInstance = nullptr;
MySingleton::MySingleton(){ };
MySingleton::~MySingleton(){
    delete singletonInstance;
};

MySingleton* MySingleton::GetInstance(){
    if (singletonInstance == NULL){
        std::lock_guard<std::mutex> lock(mtx);
        if (singletonInstance == NULL)
            singletonInstance = new MySingleton();
    }
    return singletonInstance;
}

Regarding the situations where we need to use singleton classes can be- If we want to maintain the state of the instance throughout the execution of the program If we are involved in writing into execution log of an application where only one instance of the file need to be used....and so on. It will be appreciable if anybody can suggest optimisation in my above code.

A. Gupta
  • 77
  • 2
  • 9
  • 2
    That is definitely not better. 1: You are not defining the ownership semantics by using pointer. You should never use pointers in C++ unless you prepared to manage them. 2: Your use of double checked locking is antiquated and there are much better modern ways of doing this. 3: Your comments on destruction are naive. The reclamation of memory is not the point of destructor usage it is about the cleanup. Suggestions for a better version: Look at the question. The version presented there is already much better. – Martin York Aug 12 '18 at 20:50
2

But when I need something like a Singleton, I often end up using a Schwarz Counter to instantiate it.

Matt Cruikshank
  • 2,932
  • 21
  • 24
1

I find them useful when I have a class that encapsulates a lot of memory. For example in a recent game I've been working on I have an influence map class that contains a collection of very large arrays of contiguous memory. I want that all allocated at startup, all freed at shutdown and I definitely want only one copy of it. I also have to access it from many places. I find the singleton pattern to be very useful in this case.

I'm sure there are other solutions but I find this one very useful and easy to implement.

1

I use Singletons as an interview test.

When I ask a developer to name some design patterns, if all they can name is Singleton, they're not hired.

Matt Cruikshank
  • 2,932
  • 21
  • 24
  • 46
    Hard and fast rules about hiring will make you miss out on a wide diversity of potential employees. – Karl Apr 17 '09 at 17:26
  • 13
    A wide diversity of idiots exist. That doesn't mean they should be considered for hiring. If someone can mention no design patterns at all, I think they'd be preferable over someone who knows the singleton, and no other patterns. – jalf Apr 17 '09 at 18:50
  • 3
    For the record book - my response was tongue-in-cheek. In my actual interview process, I try to assess if we will need to tutor someone in C++, and how hard that will be. Some of my favorite candidates are people who DON'T know C++ inside-and-out, but I was able to have a great conversation with them about it. – Matt Cruikshank Apr 27 '09 at 16:54
  • 4
    Down vote. From my personal experience - programmer may not be able name any other patterns but Singleton, but that doesn't mean that he uses Singletons. Personally, I was using singletons in my code BEFORE I ever heard of them (I called them "smarter globals" - I knew what the global is). When I learned about them, when I learned about their pros and cons - I stopped using them. Suddenly, Unit testing became much more interesting to me when I stopped... Does that made me a worse programmer? Pfff... – Paulius Jun 17 '09 at 18:53
  • 1
    Down vote. Good programmer knows good and bad practicies. He read Meyers and Alexandresku and all those articles that say singletons are evil (in most cases). Singleton is very deep topic. If programmer knows it, it's good. – topright gamedev Feb 10 '11 at 17:22
  • 4
    I am also downvoting for the "name some design patterns" nonsense question. Designing is about understanding how to apply design patterns, not just being able to reel off their names. Ok, that may not warrant a downvote but this answer is troll-ish. – CashCow Mar 02 '11 at 12:22
  • 1
    Downvote. If I apply as a C++ developer and Design Patterns feature that prominently in the interview, I know I don't want to work there. – DevSolar Mar 02 '11 at 13:29
  • 2
    @DevSolar design patterns are important but knowing how to apply is far more important than ability to name a list. Someone may design perfectly using all the right design patterns for the right situations and not know them by name. – CashCow Mar 02 '11 at 14:44
  • @CashCow: They *are* important, if for nothing else than communicating with fellow developers. But the "classic" patterns are for "pure" OOD... – DevSolar Mar 02 '11 at 15:41
  • @DevSolar I totally agree with you. I walked out of an interview I drove nearly 2 hours to get to because the opening question was "Do you know what a singleton is?" I replied with "yes, of course..." and was quite confused. They asked me to write one out on a laptop. I got up, thanked them for wasting my time and left, quite insulted. Sad thing is that the interviewer was the "lead developer" at Kobo Books here in Ontario. –  Nov 18 '11 at 03:08
  • I don't think that's a good test for hiring. What's your goal? Do you want someone that has experience with Design Patterns? If so, you should state that in the required experience and you should be asking them to implement or describe a pattern in addition to just naming them. If you happen to use the Singleton pattern in production (and for good reason, not just because) and you want someone that can implement the Singleton pattern, simply describe it to them and ask them to implement it. As it is, you both lose with your current hiring strategy. – Dennis Jun 30 '13 at 21:49
  • Down vote. This is not helpful to this conversation, and that seems like a rather narrow-minded approach to interviewing. – mikeyq6 Oct 10 '13 at 21:33
  • In my experience the answer to this question seems to be a fairly good indicator of depth of knowledge. If Singleton is the only pattern the interviewee can name, and they purport to be a "senior" developer... – dbugger Jul 02 '14 at 19:31
  • lmao that doesn't seem to be a very good/accurate test of programming aptitude unless you are looking for people that only know design patterns. From my personal experience, what makes a good programmer candidate is his ability to not only discuss coding concepts but relate them to the core business model of the company. – Zachary Kraus Mar 24 '15 at 06:01
0

I still don't get why a singleton has to be global.

I was going to produce a singleton where I hid a database inside the class as a private constant static variable and make class functions that utilize the database without ever exposing the database to the user.

I don't see why this functionality would be bad.

Zachary Kraus
  • 1,051
  • 10
  • 21
  • I don't understand why you think it has to be a global. – Martin York Jan 31 '14 at 04:11
  • according to this thread, Everybody was saying a singleton has to be global – Zachary Kraus Jan 31 '14 at 04:28
  • 1
    No. The thread indicates that a singelton has global state. Not that it is a global variable. The solution you propose has global state. The solution you propose is also using a global variable; a static member of a class is an object of "Static Storage Duration" a global variable is an object of "Static Storage Duration". Thus the two are basically the same thing with slightly different semantics/scopes. – Martin York Jan 31 '14 at 06:29
  • So a private static variable is still global due to the "Static Storage Duration"? – Zachary Kraus Jan 31 '14 at 14:27
  • Its scope is restricted to within the class. But you can accesses it from any part of the application. Does that not sound global? But the term "Global Variable" is meaningless in terms of the standard. There are **four** types of object in C++ "Static Storage Duration", "Automatic Storage Duration", "Dynamic Storage Duration" and "Thread Storage Duration". What you refer to as global and static members fall into the first category (the only difference is the scope under which they are visible). Apart from that what is the difference. – Martin York Jan 31 '14 at 17:15
  • 1
    Note: You missed my deliberately none stated bit. Your design of using a static "private" member is not bad in the same way as a singelton. Because it does not introduce "global mutable state". But it is not a singleton either. A singleton is a class that is designed so only one instance of the object can exist. What you are suggesting is single shared state for all objects of a class. Different concept. – Martin York Jan 31 '14 at 17:18
  • If you want a design review. Please come and visit http://codereview.stackexchange.com – Martin York Jan 31 '14 at 17:20
  • Thanks a ton. I am starting to understand. So in my case even if i only need one instantiated class since all methods will probably end up being static, a singleton is probably not the best choice. Do you have any suggestions on a design template I should use for this? – Zachary Kraus Feb 01 '14 at 14:43
0

If you are the one who created the singleton and who uses it, dont make it as singleton (it doesn't have sense because you can control the singularity of the object without making it singleton) but it makes sense when you a developer of a library and you want to supply only one object to your users (in this case you are the who created the singleton, but you aren't the user).

Singletons are objects so use them as objects, many people accesses to singletons directly through calling the method which returns it, but this is harmful because you are making your code knows that object is singleton, I prefer to use singletons as objects, I pass them through the constructor and I use them as ordinary objects, by that way, your code doesn't know if these objects are singletons or not and that makes the dependencies more clear and it helps a little for refactoring ...

La VloZ Merrill
  • 173
  • 1
  • 10
0

The Meyers singleton pattern works well enough most of the time, and on the occasions it does it doesn't necessarily pay to look for anything better. As long as the constructor will never throw and there are no dependencies between singletons.

A singleton is an implementation for a globally-accessible object (GAO from now on) although not all GAOs are singletons.

Loggers themselves should not be singletons but the means to log should ideally be globally-accessible, to decouple where the log message is being generated from where or how it gets logged.

Lazy-loading / lazy evaluation is a different concept and singleton usually implements that too. It comes with a lot of its own issues, in particular thread-safety and issues if it fails with exceptions such that what seemed like a good idea at the time turns out to be not so great after all. (A bit like COW implementation in strings).

With that in mind, GOAs can be initialised like this:

namespace {

T1 * pt1 = NULL;
T2 * pt2 = NULL;
T3 * pt3 = NULL;
T4 * pt4 = NULL;

}

int main( int argc, char* argv[])
{
   T1 t1(args1);
   T2 t2(args2);
   T3 t3(args3);
   T4 t4(args4);

   pt1 = &t1;
   pt2 = &t2;
   pt3 = &t3;
   pt4 = &t4;

   dostuff();

}

T1& getT1()
{
   return *pt1;
}

T2& getT2()
{
   return *pt2;
}

T3& getT3()
{
  return *pt3;
}

T4& getT4()
{
  return *pt4;
}

It does not need to be done as crudely as that, and clearly in a loaded library that contains objects you probably want some other mechanism to manage their lifetime. (Put them in an object that you get when you load the library).

As for when I use singletons? I used them for 2 things - A singleton table that indicates what libraries have been loaded with dlopen - A message handler that loggers can subscribe to and that you can send messages to. Required specifically for signal handlers.

CashCow
  • 30,981
  • 5
  • 61
  • 92
0

Anti-Usage:

One major problem with excessive singleton usage is that the pattern prevents easy extension and swapping of alternate implementations. The class-name is hard coded wherever the singleton is used.

Adam Franco
  • 81,148
  • 4
  • 36
  • 39
  • Downvoted for 2 reasons: 1. Singleton can internally use polymorphic instances (for example, global Logger uses polymorphic strategies of targetting) 2. There can be typedef for singleton name, so code factically depends on typedef. – topright gamedev Feb 10 '11 at 17:30
  • I ended up building my version of a singleton to be extendable using the curiously recurring template pattern. – Zachary Kraus Mar 24 '15 at 06:07
0

I think this is the most robust version for C#:

using System;
using System.Collections;
using System.Threading;

namespace DoFactory.GangOfFour.Singleton.RealWorld
{

  // MainApp test application

  class MainApp
  {
    static void Main()
    {
      LoadBalancer b1 = LoadBalancer.GetLoadBalancer();
      LoadBalancer b2 = LoadBalancer.GetLoadBalancer();
      LoadBalancer b3 = LoadBalancer.GetLoadBalancer();
      LoadBalancer b4 = LoadBalancer.GetLoadBalancer();

      // Same instance?
      if (b1 == b2 && b2 == b3 && b3 == b4)
      {
        Console.WriteLine("Same instance\n");
      }

      // All are the same instance -- use b1 arbitrarily
      // Load balance 15 server requests
      for (int i = 0; i < 15; i++)
      {
        Console.WriteLine(b1.Server);
      }

      // Wait for user
      Console.Read();    
    }
  }

  // "Singleton"

  class LoadBalancer
  {
    private static LoadBalancer instance;
    private ArrayList servers = new ArrayList();

    private Random random = new Random();

    // Lock synchronization object
    private static object syncLock = new object();

    // Constructor (protected)
    protected LoadBalancer()
    {
      // List of available servers
      servers.Add("ServerI");
      servers.Add("ServerII");
      servers.Add("ServerIII");
      servers.Add("ServerIV");
      servers.Add("ServerV");
    }

    public static LoadBalancer GetLoadBalancer()
    {
      // Support multithreaded applications through
      // 'Double checked locking' pattern which (once
      // the instance exists) avoids locking each
      // time the method is invoked
      if (instance == null)
      {
        lock (syncLock)
        {
          if (instance == null)
          {
            instance = new LoadBalancer();
          }
        }
      }

      return instance;
    }

    // Simple, but effective random load balancer

    public string Server
    {
      get
      {
        int r = random.Next(servers.Count);
        return servers[r].ToString();
      }
    }
  }
}

Here is the .NET-optimised version:

using System;
using System.Collections;

namespace DoFactory.GangOfFour.Singleton.NETOptimized
{

  // MainApp test application

  class MainApp
  {

    static void Main()
    {
      LoadBalancer b1 = LoadBalancer.GetLoadBalancer();
      LoadBalancer b2 = LoadBalancer.GetLoadBalancer();
      LoadBalancer b3 = LoadBalancer.GetLoadBalancer();
      LoadBalancer b4 = LoadBalancer.GetLoadBalancer();

      // Confirm these are the same instance
      if (b1 == b2 && b2 == b3 && b3 == b4)
      {
        Console.WriteLine("Same instance\n");
      }

      // All are the same instance -- use b1 arbitrarily
      // Load balance 15 requests for a server
      for (int i = 0; i < 15; i++)
      {
        Console.WriteLine(b1.Server);
      }

      // Wait for user
      Console.Read();    
    }
  }

  // Singleton

  sealed class LoadBalancer
  {
    // Static members are lazily initialized.
    // .NET guarantees thread safety for static initialization
    private static readonly LoadBalancer instance =
      new LoadBalancer();

    private ArrayList servers = new ArrayList();
    private Random random = new Random();

    // Note: constructor is private.
    private LoadBalancer()
    {
      // List of available servers
      servers.Add("ServerI");
      servers.Add("ServerII");
      servers.Add("ServerIII");
      servers.Add("ServerIV");
      servers.Add("ServerV");
    }

    public static LoadBalancer GetLoadBalancer()
    {
      return instance;
    }

    // Simple, but effective load balancer
    public string Server
    {
      get
      {
        int r = random.Next(servers.Count);
        return servers[r].ToString();
      }
    }
  }
}

You can find this pattern at dotfactory.com.

artur02
  • 4,469
  • 1
  • 22
  • 15
  • 3
    You could strip out the parts that are not specifically relavent to Singletons to make the code easier to read. – Martin York Sep 17 '08 at 23:46
  • Also, your first version is not thread-safe because of possible read/write reordering. See http://stackoverflow.com/questions/9666/is-accessing-a-variable-in-c-an-atomic-operation#73827 – Thomas Danecker Sep 19 '08 at 13:24
  • 5
    Uh... wrong language? The question is pretty obviously tagged **C++**. – DevSolar Mar 02 '11 at 13:31
-1

In desktop apps (I know, only us dinosaurs write these anymore!) they are essential for getting relatively unchanging global application settings - the user language, path to help files, user preferences etc which would otherwise have to propogate into every class and every dialog.

Edit - of course these should be read-only !

Martin Beckett
  • 94,801
  • 28
  • 188
  • 263
  • But this is begging the question; why do the user language and path to the help file have to be instances method _at all_? – DrPizza Sep 18 '08 at 12:18
  • 2
    We have globals for that. There's no need for making them singletons – jalf Apr 17 '09 at 18:46
  • Global variables - then how do you serialise them from registry/databse? Gobal class - then how do you ensure there is only one of them? – Martin Beckett Apr 17 '09 at 20:51
  • @mgb: you serialize them by reading values from registry/database and storing them in the global variables (this should probably be done at the top of your main function). you ensure there is only one object of a class, by creating only one object of class... really... is that hard to 'grep -rn "new \+global_class_name" .' ? really? – Paulius Jun 18 '09 at 21:18
  • 7
    @mgb: Why on Earth would I ensure there is only one? I just need to know that one instance always represents the *current* settings. but there's no reason why I shouldn't be allowed to have other settings objects around the place. Perhaps one for "the settings the user is currently defining, but has not yet applied", for example. Or one for "the configuration the user saved earlier so he can return to them later". Or one for each of your unit tests. – jalf Jul 14 '09 at 22:12
-1

Another implementation

class Singleton
{
public:
    static Singleton& Instance()
    {
        // lazy initialize
        if (instance_ == NULL) instance_ = new Singleton();

        return *instance_;
    }

private:
    Singleton() {};

    static Singleton *instance_;
};
  • 3
    That's really horrible. See: http://stackoverflow.com/questions/1008019/c-singleton-design-pattern/1008289#1008289 for a better lazy initialization and more importantly guaranteed deterministic destruction. – Martin York Jan 07 '12 at 20:45
  • If you're going to use pointers, `Instance()` should return a pointer, not a reference. Inside your `.cpp` file, initialize the instance to null: `Singleton* Singleton::instance_ = nullptr;`. And `Instance()` should be implemented as: `if (instance_ == nullptr) instance_ = new Singleton(); return instance_;`. – Dennis Jun 30 '13 at 22:00