Class Inheritence and Singletons

This topic is 3792 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

Recommended Posts

I'm reading 'Introduction to 3D Game Programming with DX 9.0c a shader approach' by F.Luna. When reading Chapter 4 and looking at the source code (a basic DX9 app) i noticed that Luna has a d3dApp class that he uses as a base for all the demos in the book. So the idea is you want to make an app, create your class and have it use the d3dApp as its base. Override the pure virtual functions and your good to go, right? In the comment at the top of d3dApp class header file he states this; 'Clients are to derive from D3DApp, override the framework methods, and instantiate only a single instance of the derived D3DApp class. At the same time, the client should set the global application pointer (gd3dApp) to point to the one and only instance, e.g., gd3dApp = new HelloD3DApp(hInstance)' The above rings alarms in my head as it sounds like using the Singleton pattern would be a good idea here. However i'm a bit confused when this involved deriving a class from d3dApp, and which part should be the singleton. Have i got the complete wrong end of the stick here? It is possible to derive from this class and use the singleton pattern? i.e. In my head the derived class should be a singleton and hence would return the only instance of the d3dApp. But this sounds to easy, should i be looking out for pitfalls here. Any help to understand this would be much appreciated.

Share on other sites

Best solution would be to remove the global and pass the variable by reference to any function that needs it.

Share on other sites
Just because there is only one doesn't mean it has to be a singleton. A singleton is only for the time in which you have to guaranty singleness and can't stop yourself from trying to make more than one. In this case you can create one and through sheer willpower and self control not create a second one, there by making the singleton pattern over kill and a waste of time. Also He is trying to teach you the API, while learning that try not to pickup his absolute lack of software design.

Share on other sites
Quote:
 Original post by stonemetalwhile learning that try not to pickup his absolute lack of software design.

I appreciate that code samples are obviously geared towards teaching me the API rather than good design. I wasn't being critical i was just trying to apply my other knowledge to this situation.

I guess as it turns out my understanding of Singletons is flawed and i will make sure to read the link that was provided, thanks rip-off.

But i'm confused by your comment about pass by reference to functions. The global in question here is a pointer to an instance of the derived application class. If this is created in say WinMain, won't it be quite a lot of work to pass it down to everything that needs it? If you could clarify this that would be great.

Share on other sites
Quote:
 Original post by JimmyDeemoBut i'm confused by your comment about pass by reference to functions. The global in question here is a pointer to an instance of the derived application class. If this is created in say WinMain, won't it be quite a lot of work to pass it down to everything that needs it? If you could clarify this that would be great.

Not as much as you might think. Applications (not just games) are often divided up into the Model, View and Controller architecture. You'll only need a reference to a D3D instance in the View. The fact that you have to pass a reference around will encourage you to split your program sensibly.

Share on other sites
Quote:
 won't it be quite a lot of work to pass it down to everything that needs it? If you could clarify this that would be great.

Yes and no.

Chances are that if the object was originally a global or singleton, than it will appear as if needs to be passed to almost everything. This is usually because either (a) you are assuming a global is actually accessed globally by almost every subsystem, or (b) it is actually accessed globally by almost every subsystem.

You'd want to hope for (a), but since we're talking about a singleton or global, chances are you're going to get mostly (b) since it is what happens with bad design (and bad design and globals/singletons usually go hand-in-hand). (a) is just what happens when you lack experience, which isn't nearly as terrible.

Anyway, the solution is still to pass it everywhere it is needed. But the key word here is "needed" not "everywhere." In fact, in a well designed system that "application instance" object will be needed by... nothing at all, other than itself and the class that derives from it. The application instance is the top-level object in your game, and so should be created and manipulated in WinMain and basically nowhere else.

Part of good design involves minimizing your dependancies and isolating subsystem interaction through clear interfaces, points of contact, or management by higher level specific subsystems. Passing former globals or singletons around to all the required locations helps make your interdependancies explicit, and thus will help you find the points where you need to refactor your code to operate in a more "standalone" mode.

When all is said and done you should find you have a relatively small amount of passing stuff around. It will take some time, certainly, because it's not neccessarily a trivial skill -- but it's a very good one to learn.

Share on other sites
Yeah i guess that if i find myself getting into a pickel with passing things around then its probably bad design. I should probably not even be concerning myself with issues like this and concetrate on learning what the book is trying to teach me.

EDIT: Having looked more into the source code i can see that, in this case, its only a global for convenience and probably readablility. At least now i will consider what i should be passing around and also whether i actually need to pass it as deep as i might do.

Share on other sites
I mostly do 2d games and use opengl occasionally, but my rendering code is usually quite flat, usually less than four function calls deep that might make use of a screen handle or something like that, so I would say no passing a reference around isn't that big a deal. If it is truly an app class then the "this" pointer should always be readily available making the global redundant at best.

Share on other sites
Hey!

I am using and learning from the same book as the one you've mentioned. Frankly, I thought of the same thing by reading that. In my case, what I did was to make my class a singleton and inheritable. You can actually use any of both approaches to make the game.

Honestly, while programming it, I'm still using the inheritance approach and I still haven't encountered the need of the singleton-ability. Inheritance is perfect the way it is.

Share on other sites
As a follow up to the whole pass the reference around thing. I noticed that he uses the global in the msgproc function here;

LRESULT CALLBACKMainWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam){	// Don't start processing messages until the application has been created.	if( gd3dApp != 0 )		return gd3dApp->msgProc(msg, wParam, lParam);	else		return DefWindowProc(hwnd, msg, wParam, lParam);}

How would i do this without the use of a global? I could make MainWndProc a member function, but that would mean it needs to be static right? Doesn't that have other implications? Advice much appreciated.

1. 1
Rutin
19
2. 2
3. 3
4. 4
5. 5

• 15
• 13
• 9
• 12
• 10
• Forum Statistics

• Total Topics
631442
• Total Posts
3000101
×