![]() |
| [[ Home | Forums | 3D Engines Database | Wiki | Articles/Tutorials | Game Dev Jobs | IRC Chat Network | Contact Us ]] |
|
|
#1 |
|
Member
Join Date: Jan 2003
Posts: 85
|
For those who don't know, a Singleton is an object that can only have one instance in the lifetime of the program. Here's the class to inherit from to make a singleton class. This is taken from the GEMS series.
Singleton.h ------------- Code:
Example of usage: ----------------------- Code:
Now OpenGLRenderer can only be created once. Attempting to create again (using the 'new' keyword) will cause an assertion to warn you. Example of usage: Code:
|
|
|
|
|
|
#2 |
|
DevMaster Staff
Join Date: Sep 2003
Location: Hell
Posts: 1,109
|
you shouldn't use that hacky offset thing in teh ctor becaus eof incompatability issues. a simple static_cast would do just fine, and here's why
and for those that are inerested, here's the online description of that from the guy who wrot eit in the gems book. |
|
|
|
|
|
#3 |
|
DevMaster Staff
Join Date: Apr 2003
Location: Germany
Posts: 2,328
|
especially since i see no real need for this class at all. the thing is that as soon as you start using dlls your singleton pointer won't work over library boundaries because each dll would reimplement the static pointer locally. to solve this you would have to provide a static overload of the getSingleton method in each class that derives from Singleton. what remains is that you have abstracted the storage of the singleton pointer in a hacky and ugly way (the static_cast would take away the uglyness but still the whole thing would be more of an OOP beautification than being really useful)
___________________________________________
If Prolog is the answer, what is the question ? |
|
|
|
|
|
#4 |
|
Senior Member
Join Date: Jan 2003
Location: Switzerland
Posts: 1,333
|
i hate singletons.. but okay.. having it around is fine (for more details about why, just browse the net.. there are tons of discussions
)
___________________________________________
davepermen.net -Loving a Person is having the wish to see this Person happy, no matter what that means to yourself. -No matter what it means to myself.... |
|
|
|
|
|
#5 |
|
Senior Member
Join Date: Aug 2004
Location: USA
Posts: 829
|
It is not something I would ever use but it is still neat to see a singleton implemented as an inhereted templated class that takes its decendant as a parameter. I wonder if code errors are produced in programs by inbreading just as they are in people.
![]() I do question what happens when you make a subclass of your chosen singleton. I suppose you would have to resign yourself to never doing this. Though I guess you could always recast the returned pointer by hand afterward.
___________________________________________
Jesse Coyle |
|
|
|
|
|
#6 |
|
New Member
Join Date: Sep 2004
Posts: 9
|
Only want one opengl renderer?! Maybe in a very simple application, like a game. Not in, say, tools.
Anyway, what's wrong with:- Code:
The object isn't constructed until Singleton is first called, and it works across DLL's. |
|
|
|
|
|
#7 |
|
Senior Member
Join Date: Jan 2003
Location: Switzerland
Posts: 1,333
|
nothings wrong with it. we still have to care manually about uninitialisation of the renderer. and still, singletons are not my thing, i don't like them.
___________________________________________
davepermen.net -Loving a Person is having the wish to see this Person happy, no matter what that means to yourself. -No matter what it means to myself.... |
|
|
|
|
|
#8 |
|
Senior Member
Join Date: Jan 2003
Posts: 868
|
I doupt that someone likes them cause in the most cases their implementation is extremely hacky like the one above.
And i remember seeing in the HL2 sources (which of course i don't have on my hard disk!!!) that Valve also uses the most simple variant knackered showed. However this implementation posses great danger about deinitialization since i'm not exactly sure when the destructor is called... |
|
|
|
|
|
#9 |
|
New Member
Join Date: Sep 2004
Posts: 9
|
Destruction happens when the module is unloaded, or the application terminates in the same way that all other statics are destructed. The order of statics destruction is undefined, however.
|
|
|
|
|
|
#10 |
|
Senior Member
Join Date: Jan 2003
Location: Switzerland
Posts: 1,333
|
yeah, and this order can be important sometimes.
but my main reason i don't like singletons is another one. where-ever i design some sort of object, even while i think i will only need it once, and only once, there will be the day i just put it into vector, or what ever, and have several of them. i never had a singleton that survived for long time as a real singleton, and ended as just another class, with possibly a global interface to the instances. but about never it stayed at only one instance.. well well.. my little rant about singletons..
___________________________________________
davepermen.net -Loving a Person is having the wish to see this Person happy, no matter what that means to yourself. -No matter what it means to myself.... |
|
|
|
|
|
#11 |
|
Senior Member
Join Date: Aug 2004
Location: USA
Posts: 829
|
Dave, that is actually the entire reason for using Singletons instead of a bunch of global functions or a class of static functions. In this way the only change you have to make is to remove the getInstance function and make the constructor pubic and you are done.
___________________________________________
Jesse Coyle |
|
|
|
|
|
#12 |
|
Member
Join Date: Sep 2004
Posts: 33
|
Um, shouldn't the con/destructor in that code be made private, and a static GetInstance() method (or whatever) added to the class? Otherwise there's very little stopping you from buggering the whole implementation...
___________________________________________
Def Base [ 32Bits.co.uk - Coding for real people! ] |
|
|
|
|
|
#13 |
|
Valued Member
Join Date: Aug 2004
Posts: 120
|
I am a huge advocate of OOP, but sometimes you just need to pick the best tool for the job. What I am saying is that you can build a singleton as free functions (with Init and Uninit functions) or, preferably, make your singleton a global pointer variable. That gives you full control over lifetime and eliminates any hack or weird singleton mechinism.
If you go with the global variable, you can add this line to your objects contructor: ASSERT(pGlobal == NULL) Simple and effective. |
|
|
|
|
|
#14 |
|
Senior Member
Join Date: Jan 2003
Location: Switzerland
Posts: 1,333
|
i don't see the purpose of "having a class that can only be instanciated once".
i do see the use of modules (often my factories are modules), and the fact that sometimes, i only want one global instance of my class. but restricting a class to only be instanciable one time. i see no use for this.. this sounds irritating.
___________________________________________
davepermen.net -Loving a Person is having the wish to see this Person happy, no matter what that means to yourself. -No matter what it means to myself.... |
|
|
|
|
|
#15 |
|
Valued Member
Join Date: Jan 2004
Location: England
Posts: 265
|
The singleton class here is very similar to the one posted in the Enginuity articles posted on GameDev. Useful to some but I had a lot of issues with it that ment that it had to be removed.
The offsetting code, while working in VS .net doesnt work in VC6, and, as has been mentioned, it is not a viable option when using dll's. I would be interested to know how wide spread the use of proper sngletons is in general game programming, because for me, it is to restrictive, and in some cases, excessive for general use. Spree |
|
|
|
|
|
#16 |
|
New Member
Join Date: Oct 2005
Posts: 6
|
Well if you are unable to implement singleton or are have too much problems doing it, you can try a class with all its members as static, and just add Setup() and End() methods or something.
With the help of a bool vairable you can make an Init function that initializes the 'class' as long as it wasn't initialized , for those cases where you can't be sure which modulo loads first Last edited by Vexorian : 11-14-2005 at 08:51 PM. |
|
|
|
|
|
#17 |
|
DevMaster Staff
Join Date: Oct 2004
Location: Seattle, WA
Posts: 3,707
|
I agree with davepermen on this one. A singleton's just a hidden global variable, so why not just make it a global variable (in a namespace if you want)? Chances are, sooner or later you will think up a situation where you want to be able to have more than one instance of this class. The effort needed to implement a proper singleton in C++ is, imho, not worth its very dubious benefits.
___________________________________________
Currently working at Sucker Punch reedbeta.com - OpenGL demos and other projects Luabridge - a lightweight, dependency-free C++/Lua binding library. CD Lite - an unobtrusive, minimal CD player application for Windows. |
|
|
|
|
|
#18 |
|
DevMaster Staff
Join Date: Sep 2005
Location: The Netherlands
Posts: 1,442
|
Reedbeta: global variables are poor design in the sense they can be altered. If you hide the variable with an accessor, you can only read the instance and not write.
Also, having to pass around tons of pointers can be pretty tedious, so having singleton accessors makes live much easier. If you really want to be able to create more than a single instance of a class, I suggest putting all the accessors in a class that also holds all the references to the singletons, so you can hold a single pointer to that class.
___________________________________________
C++ addict - Currently working on: the 3D engine for Tomb Raider: Underworld and Deus Ex 3. |
|
|
|
|
|
#19 | |
|
DevMaster Staff
Join Date: Oct 2004
Location: Seattle, WA
Posts: 3,707
|
Quote:
Yes, this is exactly what I do. I have a State class that holds all the things that would otherwise be global variables. There is typically just one global instance of this class, but it it allows for expansion to more (for instance, if I was writing a raytracer, I might want to expand it to a "render server" that could simultaneously process multiple independent rendering jobs).
___________________________________________
Currently working at Sucker Punch reedbeta.com - OpenGL demos and other projects Luabridge - a lightweight, dependency-free C++/Lua binding library. CD Lite - an unobtrusive, minimal CD player application for Windows. |
|
|
|
|
|
|
#20 |
|
DevMaster Staff
Join Date: Apr 2003
Location: Germany
Posts: 2,328
|
The Singleton is probably most useful, when you need to make clear to others, by design, that a class is supposed to exist only once in a system. Always remember that the people who write software architecutures and those who implement them are often not the same.
I agree though that especially on windows the pattern is plagued by far too many problems.
___________________________________________
If Prolog is the answer, what is the question ? |
|
|
|
|
|
#21 |
|
Senior Member
Join Date: Oct 2005
Posts: 745
|
I do find that I side with Reedbeta in one aspect:
Most of my singletons end up marching up the line and end up becoming 'managed' instances: that is, I end up having more than one. It's funny however then, because then the item that's 'managing' those instances usually becomes the singleton, and the singleton itself is relatively easy to extract from such an implementation. On a somewhat related note: has anyone ever looked at Loki Lib? (http://sourceforge.net/projects/loki-lib/) It's supposed to make implementing design patterns such as the singleton much easier to roll out. I'm curious how it fares.
___________________________________________
Kicking Dragon (dot) com - Technical Ramblings of a Game Programmer |
|
|
|
|
|
#22 |
|
Senior Member
Join Date: Oct 2005
Location: Pensacola, FL
Posts: 1,028
|
I've had experiences with MSVC++ 7.1 optimizing out singleton implementations like the one knackered showed with the "Maximize Speed (/O2)" setting:
Code:
It seems to make the code behave like this: Code:
...and that's obviously bad. Does anyone know how to predict and/or prevent this behavior? Or am I just crazy, and noone else has had this problem? |
|
|
|
|
|
#23 |
|
DevMaster Staff
Join Date: Sep 2005
Location: The Netherlands
Posts: 1,442
|
Are you sure? It works fine on my machine...
S.h Code:
main.cpp: Code:
foo.cpp: Code:
output: Code:
___________________________________________
C++ addict - Currently working on: the 3D engine for Tomb Raider: Underworld and Deus Ex 3. Last edited by .oisyn : 11-17-2005 at 08:34 AM. |
|
|
|
|
|
#24 |
|
Senior Member
Join Date: Oct 2005
Location: Pensacola, FL
Posts: 1,028
|
It definitely works most of the time. I've only had the problem once and I don't know why. Anyway, I've decided to avoid the use of singletons whenever possible. The case that caused the problem was a rush job in which the singletons substituted for good design.
NOTE: I'm not intending to start another singletons are bad discussion! I don't have enough experience to comment either way. |
|
|
|
|
|
#25 | |
|
New Member
Join Date: Aug 2005
Location: San Francisco, MA
Posts: 24
|
Quote:
Can you elaborate on this? I've never had any problem with exporting from a DLL a class derived from a singleton template like this one. I have had problems when the derived class was also templated, but that can be solved by exporting specializations of the singleton. Max |
|
|
|
|
![]() |
| Thread Tools | Search this Thread |
| Display Modes | |
|