Am I crazy? what is a singleton?

Started by
20 comments, last by Zahlman 19 years, 9 months ago
I really only use singletons for lazy initialization of things. If I have to construct a message routing window, I won't actually do so unless I must. Singleton does make that easier.

But yes, most people throw a singleton in and mistakenly think that since it is a design pattern it is somehow cleaner. Bzzt, a global is still a global by any other name.

And I prefer monostate to singleton anyway.
--God has paid us the intolerable compliment of loving us, in the deepest, most tragic, most inexorable sense.- C.S. Lewis
Advertisement
The only argument for singletons that I can agree with is that if you make something static you can't control exactly how and when it's created (at least I've heard this argument several times).

Singletons is something that popped up in a "famous" game-programming book and everybody wanted to be cool and started to use it. As I see it singletons can make global hell a bit colder but still if you have an oo design then you're fine anyway....
I think antareus stated the right reason to use it: sometimes you need either 0 or 1 instances of a particular class, and always using a static Singleton.get method to access the object lets you not worry about wheteher and when it will be initialized. At least, that's all I've seen in singleton implementations - the only extra trick is to make them thread-safe; there are apparently a dozen ways to do this wrong in Java, so every Java site writes an article about how to properly use singletons. You only need to use this for objects which are expensive to instantiate and which are not used every time the program is run. For example, a connection to a database, a script interpreter, or a large lookup table.
Quote:Original post by Zahlman
- to solve static order of initialization problems. (Which, in Java at least, are a Can't Happen(TM), unless you have a cyclic dependency that would need some other resolution strategy *anyway*. C++ certainly allows the possibility though.)


Singleton's in C++ cause far more initialization problems than they solve.

Quote:
- to allow runtime polymorphism in order to select some singleton subclass to treat as "the instance" (I am told this gets used for abstracting away rendering layers when you - somehow! - don't know until runtime which graphics API you're going to use.)


Bingo! Regard cin & cout as legacy examples
- The trade-off between price and quality does not exist in Japan. Rather, the idea that high quality brings on cost reduction is widely accepted.-- Tajima & Matsubara
Quote:Original post by Magmai Kai Holmlor
Quote:Original post by Zahlman
- to solve static order of initialization problems. (Which, in Java at least, are a Can't Happen(TM), unless you have a cyclic dependency that would need some other resolution strategy *anyway*. C++ certainly allows the possibility though.)


Singleton's in C++ cause far more initialization problems than they solve.


Ironically enough, earlier today I was pondering that "now they have two problems" quote about regexes, applying it to singletons instead. :)

Quote:
- to allow runtime polymorphism in order to select some singleton subclass to treat as "the instance" (I am told this gets used for abstracting away rendering layers when you - somehow! - don't know until runtime which graphics API you're going to use.)


Bingo! Regard cin & cout as legacy examples

... Why wouldn't the program know at compile time what cin and cout are? Won't they always have the same implementation for the platform being compiled on?
Grr, GD forgot my cookie >__<
Quote:Original post by Zahlman
Quote:Original post by Jingo
Singletons are not replacements for globals. The only thing they have in common is the global point of access. The singleton pattern ensures that there is only one instance of a class, a global does not do this.


I could be completely misunderstanding, but when I fill in the missing words and substitute the backreferences in "a global does not do this", I get "using a global variable does not ensure that there is only one instance of the global variable."



No, you get "using a global variable does not ensure that there is only one instance of a class".
A singleton will prevent the global being changed in the middle of your code to point to something else.
RenderManager *renderManager;void DoSomethingInMiddleOfGameLoop(){    //...    renderManager = new RenderManager;    //...}

Of course you would be an idiot if you actually did this, and if your were working with someone that did then they shouldn't be there for much longer.
"Voilà! In view, a humble vaudevillian veteran, cast vicariously as both victim and villain by the vicissitudes of Fate. This visage, no mere veneer of vanity, is a vestige of the vox populi, now vacant, vanished. However, this valorous visitation of a bygone vexation stands vivified, and has vowed to vanquish these venal and virulent vermin vanguarding vice and vouchsafing the violently vicious and voracious violation of volition. The only verdict is vengeance; a vendetta held as a votive, not in vain, for the value and veracity of such shall one day vindicate the vigilant and the virtuous. Verily, this vichyssoise of verbiage veers most verbose, so let me simply add that it's my very good honor to meet you and you may call me V.".....V
It's a particularly clumsy way of writing a global variable.
char a[99999],*p=a;int main(int c,char**V){char*v=c>0?1[V]:(char*)V;if(c>=0)for(;*v&&93!=*v;){62==*v&&++p||60==*v&&--p||43==*v&&++*p||45==*v&&--*p||44==*v&&(*p=getchar())||46==*v&&putchar(*p)||91==*v&&(*p&&main(0,(char**)(--v+2))||(v=(char*)main(-1,(char**)++v)-1));++v;}else for(c=1;c;c+=(91==*v)-(93==*v),++v);return(int)v;}  /*** drpizza@battleaxe.net ***/
I know two cases where a singleton may be useful:

1) The class is part of a class hierarchy and needs to override some virtual functions. For example, it can be useful to have a "dummy" or "empty" object that does nothing. It would be a waste to create several such objects. In this case, you get the object with the Instance() function but you still pass the pointer in a bigger system that is unaware of the existance of the singleton.

2) You have only one instance right now, but you plan to have several later. In this case, the change will be smaller if the object is defined as a class in the first place.

Otherwise, a namespace with functions that "privately" access data defined in the source file (.cpp) is a much better approach I think. It separate interface and implementation even more than a class without the cost of using virtual functions (which are the way to separate those with classes)

alexk7

[Edited by - alexk7 on July 7, 2004 7:29:46 PM]
alexk7

This topic is closed to new replies.

Advertisement