extending singleton?

Started by
7 comments, last by supagu 20 years ago
okay, i have done most of my managers as singletons in my engine, but now i want to extend the singleton, eg: I have a World singleton, which loads and renders the world... now i want to extend this eg: MyCustomWorld : public World but then where i have code that access the world: eg: World::GetInstance().SomeFN(); would need to be replaced like this: MyCustomWorld::GetInstance().SomeFN(); the only way i can see this happening is some how deleting the instance of World and making it point to an instance of MyCustomWorld, but any info in World would be lost!? ideas? with my old engine, i made an Engine class, which held pointers to all managers (instead of them being a singleton) so my Engine was an uber interface eg: Engine::GetInstance().GetRenderManager().SomeFN(); this worked well, and allowed me to plug in another rendermanager or world or what ever, maybe i should go back to this idea? so then Engine would be the only singleton!
Advertisement
Templates are your friends!

Have your singleton have its instance pointer as a templated type:
template<class T>class Singelton{T* instance;}


Then when world inherits from it, it would look like this:
class World : public Singleton<World>{// stuff}

What you can do to solve your problem is to template world like this:
template<class T>class World : public Singleton<T>{// stuff}


Then you just do this, and voila!
class GameWorld : public World<GameWorld>{// stuff}
Shields up! Rrrrred alert!
Ew.

Making a singleton implies that you only want one of something to exist.

Subclassing the thing implies that you want different types of the thing to exist.

There is a contradiction in the thought process here.

Consider un-singletonizing your World. Consider a design pattern like Factory or AbstractFactory to provide appropriate World subclasses to the client code.
quote:
Subclassing the thing implies that you want different types of the thing to exist.

There is a contradiction in the thought process here.


I must disagree, that does not have to be the case

Imagine that you have a singleton handlemanager which associates handles with internal data. A natural step here would be to derrive a Texture Handler and a Sound Handler from the handle manager, for instance.
Shields up! Rrrrred alert!
Far from a natural step. If you need to inherit from your handle manager, that means that it cannot be a singleton, since right in your example you have listed that it can be specialized into a sound manager and a texture manager. The sound manager should be a singleton, but the handle manager should never be created on its own (since it has been replaced by the specialized managers), and should not be a singleton. Besides, wouldn''t you inherit from texture manager with private inheritance? It''s not like you pass around sound manager pointers, and need to have access to solely the handle manager parts.
quote:
Far from a natural step. If you need to inherit from your handle manager, that means that it cannot be a singleton, since right in your example you have listed that it can be specialized into a sound manager and a texture manager.

Ofcourse it can be a singleton. And i belive it should, lets say that if a class wants to be a handlemanager, it also has to be a singleton in this example.
Then dont you agree that handlemanager beeing a singleton is more logical than having to remember that each class that uses the handlemanager interface have to remember to also inherit from the singleton? Since the instance pointer in the singleton is templated, inheriting from it works just fine, and the same static instance wont be shared by a base class and a class inheriting from it, since they are diffrent types.


quote:
The sound manager should be a singleton, but the handle manager should never be created on its own (since it has been replaced by the specialized managers), and should not be a singleton.

The handle manager cannot be created on its own any more then a pure singleton can be created on its own, these are instance templated classes, they are at no point instanceated unless properly inherited from.

quote:
Besides, wouldn''t you inherit from texture manager with private inheritance? It''s not like you pass around sound manager pointers, and need to have access to solely the handle manager parts.

That is correct i guess
Shields up! Rrrrred alert!
quote:Original post by peter_b
quote:
Far from a natural step. If you need to inherit from your handle manager, that means that it cannot be a singleton, since right in your example you have listed that it can be specialized into a sound manager and a texture manager.

Ofcourse it can be a singleton. And i belive it should, lets say that if a class wants to be a handlemanager, it also has to be a singleton in this example.
Then dont you agree that handlemanager beeing a singleton is more logical than having to remember that each class that uses the handlemanager interface have to remember to also inherit from the singleton? Since the instance pointer in the singleton is templated, inheriting from it works just fine, and the same static instance wont be shared by a base class and a class inheriting from it, since they are diffrent types.

Of course not.

If you insist that a handle manager can not exist on its own, and that it should simply be derived from, then that is the job of an Abstract Base Class, NOT a singleton.


[edited by - mfawcett on April 12, 2004 1:31:09 PM]
--Michael Fawcett
quote:Original post by mfawcett
quote:Original post by peter_b
quote:
Far from a natural step. If you need to inherit from your handle manager, that means that it cannot be a singleton, since right in your example you have listed that it can be specialized into a sound manager and a texture manager.

Ofcourse it can be a singleton. And i belive it should, lets say that if a class wants to be a handlemanager, it also has to be a singleton in this example.
Then dont you agree that handlemanager beeing a singleton is more logical than having to remember that each class that uses the handlemanager interface have to remember to also inherit from the singleton? Since the instance pointer in the singleton is templated, inheriting from it works just fine, and the same static instance wont be shared by a base class and a class inheriting from it, since they are diffrent types.

Of course not.

If you insist that a handle manager can not exist on its own, and that it should simply be derived from, then that is the job of an Abstract Base Class, NOT a singleton.


[edited by - mfawcett on April 12, 2004 1:31:09 PM]


You are wrong i belive. Consider this:
template<class T>class Singleton{T* inst;}// Handle Managertemplate<class T>class HandleManager : public Singleton<T>{}// Texture Managerclass TextureManager : public HandleManager<TextureManager>{}


Now, while it would be possible to instanceiate a handlemanager that dosn't handle anything with doing: HandleManager < HandleManager > ::getInstance() unless it is abstract, i dont think that is a terrible problem. But as i said, if you want it abstract, design it that way. (but in supagu's example with his world singleton, it may would be useful)


If i get you right, you would rather have it this way:
class TextureManager : private HandleManager, public Singleton<TextureManager>{}


I can't see why that would be any better, infact, its alot worse. If you know that a handlemanager will always be a singleton, surley it must be better to force that and not rely on the user to remember it.





[edited by - peter_b on April 12, 2004 1:55:22 PM]

[edited by - peter_b on April 12, 2004 1:55:59 PM]
Shields up! Rrrrred alert!
I think we''ll have to agree to disagree, peter_b. Nothing said thus far has convinced me in the slightest bit.

With the ABC approach, users are free to make the design choice themselves, rather than be forced into the singleton pattern.

What if you had multiple rendering contexts? Does the singleton pattern still make sense? Is it easily scaled to support multiple rendering contexts? IMO, the answer is no to both questions, whereas with the ABC design, you simply make another instance of the classes needed, and you''re good to go.
--Michael Fawcett

This topic is closed to new replies.

Advertisement