![]() |
| [[ Home | Forums | 3D Engines Database | Wiki | Articles/Tutorials | Game Dev Jobs | IRC Chat Network | Contact Us ]] |
|
|
#1 |
|
Posts: n/a
|
This is standard singleton implementation, with a twist from my own.
First, I write the singleton implementation code: Code:
Followed by what I call a handle: Code:
Then, to use this singleton, you instanciate a handle like so: Code:
What do you think? Eric B. |
|
|
|
#2 |
|
DevMaster Staff
Join Date: Oct 2004
Location: Seattle, WA
Posts: 3,707
|
I think that's a cool way of doing it. It certainly makes using the singleton syntactically nicer (no MySingleton::getInstance junk everywhere). And because you have another layer between the users and the actual singleton object, you have a bit more flexibility about policy; you could easily change from a true global singleton to a one-per-thread 'singleton', for instance.
On the other hand, you have to write a forwarding method for every method of the singleton (and update these every time the singleton's methods change). Also there's nothing in the code you showed about controlling destruction order, which can be an issue (though your method does allow construction order to be controlled rather elegantly).
___________________________________________
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. Last edited by Reedbeta : 12-09-2007 at 01:39 PM. |
|
|
|
|
|
#3 |
|
Member
Join Date: Jul 2007
Posts: 92
|
Or you could create a singleton smart pointer:
Code:
Code:
Last edited by J22 : 12-08-2007 at 02:25 PM. |
|
|
|
|
|
#4 |
|
Valued Member
Join Date: Nov 2004
Location: Milan -ITALY-
Posts: 297
|
Hi,
one wouldn't want the singleton to auto-delete as one of the instances of the handler class goes out of scope, so invoking a delete from inside a destructor is not an option. Therefore the handler class could expose a method to be explicitly invoked (by the client) when he wishes to release the singleton. Since the singleton is handled through a static pointer, nulling it will safely affect each and every instance of the handler class still in scope, and for free too. Ciao ciao : )
___________________________________________
-Nautilus 1.551640271931635485e+1292913986 ? Why, that's: 2 ^ ((2 ^ (2 ^ ((2 ^ 2) + (2 ^ (2 - 2))))) - (2 ^ (2 - 2))). Now verify, please... |
|
|
|
|
|
#5 | |
|
Valued Member
Join Date: Oct 2005
Posts: 247
|
Quote:
___________________________________________
http://www.iguanademos.com/Jare |
|
|
|
|
|
|
#6 |
|
DevMaster Staff
Join Date: Oct 2004
Location: Seattle, WA
Posts: 3,707
|
If singleton B depends on singleton A already having been initialized, you can just instantiate a handle to A in B's constructor (the implementation constructor, not the handle constructor). As long as you have no cycles in your singleton dependency graph, everything will sort itself out and be constructed in the right order and as late as possible (i.e. not till it's actually needed).
Unfortunately there doesn't seem to be quite such an elegant way to make things automatically destruct in the right order. Of course you can always insert explicit deletes at the bottom of main() or something like that, but that seems brittle, since if you add a new singleton or change the dependencies between singletons, you can easily forget to update the deletion code.
___________________________________________
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. |
|
|
|
|
|
#7 |
|
Valued Member
Join Date: Aug 2005
Posts: 189
|
Singletons are just hard. Code that relies too much on singletons runs into problems sooner or later. There are two reasons, a technical one and a ... other one. The technical one is singleton destruction. If singletons start to depend on other singletons, using the naive implementation as above, there's just no way that you will get the order of destruction right. The other one is that what one day seems to be a perfectly valid reason to implement a singleton, turns out to be a situation where you need two instances after all on the other day.
Andrei Alexandrescu has some great solutions for singleton implementations in his book Modern C++ design, solving the former problem with a longevity "register". Also he deals with some multithreading issues (what happens if both threads want to create the singleton instance at the same time?). For the latter problem, I find one step into the right direction not to design the class as a singleton, but to "use" it as a singleton. J22's SingletonPtr comes close to that idea. Seperate the singleton pattern from the class, so that you can always create more instances of the class if necessary. Of course, that still doesn't solve the issue where you need two seperated "instances" of code that _use_ singletons. Say, you have some code that uses a singleton and one day you want to run the same code on multiple threads, but completely seperated: i.e. they should not use the "same singleton". Then what? There are some ways of course to help the situation. Sometimes you will be able to use the same singleton after all if you add some locking, or you can use Thread Local Storage tricks to have a singleton per thread. But at the end of the day, it's better to design without singletons if it is at all possible. Cheers, Bramz
___________________________________________
hi, i'm a signature viruz, plz set me as your signature and help me spread :) Bramz' warehouse | LiAR isn't a raytracer |
|
|
|
|
|
#8 |
|
Senior Member
Join Date: Aug 2004
Location: Thornhill, TO
Posts: 850
|
The thing I don't like about singletons is when you're dealing with DLLs. They have their own memory space, so you can end up with multiple singletons floating around.
I find using factories work quite well in combination with singletons, since factories isolate objects in their own memory space and can guarantee only one instance of it is created. I also wouldn't worry about deleting singletons. In most cases, the reason you have them is because you only want one instance of it in the entire program. The object could have special flags and other states, so it may be important to keep the singleton alive for the duration of the program even when you're not using it. You could also run into memory access issues if you are dealing with DLL files.
___________________________________________
http://www.nutty.ca - Being a nut has its advantages. |
|
|
|
|
|
#9 | |
|
DevMaster Staff
Join Date: Oct 2004
Location: Seattle, WA
Posts: 3,707
|
Quote:
It's nice to be able to gracefully cleanup singletons, like closing net connections, closing files, releasing memory and so on. Granted that this isn't *actually* necessary on most modern OSes as the kernel will close files and so forth for you (in most cases). Still, I feel it's a good programming practice.
___________________________________________
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. |
|
|
|
|
|
|
#10 |
|
New Member
Join Date: Sep 2005
Location: Rome
Posts: 9
|
Call me noob, but shouldn't:
Code:
actually be: Code:
?
___________________________________________
To live is to be eager to die. |
|
|
|
![]() |
| Thread Tools | Search this Thread |
| Display Modes | |
|