OO help

Started by
12 comments, last by ToohrVyk 16 years, 3 months ago
Hi, q1)When the user inputs keystrokes I find I am having too many lines of code in my main file, so i want to move this code to another file. I test a key by this where VK_RIGHT is a 0x27 if( GetAsyncKeyState(VK_RIGHT) & 0x8000f ) cam.yaw(0.001f);..etc if( GetAsyncKeyState(VK_LEFT) & 0x8000f ) cam.yaw(-0.001f); .... for another 12 keys i want to test and keystroke with a variable then test the variable to see what it is (in another file). SO how can i do this or is there a better way? q2)I have a clas in a .h file and also i have the class functions in the .h file. Should i have this in another .cpp file instead? void camera::roll(float angle) { ... this.setMatrices(); //this function is also in the same file but it fails with the this keyword?why? q3) i am using some variables in my class defined globally or elsewhere. Is this bad OO design?
Advertisement
1) If you do not like having a lot of code in one file you could change it to an object or a function that deals with it for you so you need only call one function instead of having the code in the file. Be aware though that as the complexity of a project grows the size of the files do as well so do not go out of your way to avoid it.

2) The most common way I have personally seen is to have a .h file and a seperate .cpp file for the implementation. That is good if you wish to sell code so you can just give buyers the .h file and the object file if you do not want them seeing or mucking with your code. Other than that it is a matter of personal preference. Be aware that if you write out an entire class in a .h file without seperate functions then the compiler will try to inline them all which could cause executable bloat.

the "this" keyword refers to the object that the function is in. So if the object you are trying to call setMatricies in does not have that function then you have an error

3) Get rid of global variables, that is the exact opposite of what object oriented programming strives for. They are even a bad idea in functional programming.
Quote:Original post by jagguy2
Hi,
q1)When the user inputs keystrokes I find I am having too many lines of code in my main file, so i want to move this code to another file.

I test a key by this where VK_RIGHT is a 0x27

if( GetAsyncKeyState(VK_RIGHT) & 0x8000f )
cam.yaw(0.001f);..etc
if( GetAsyncKeyState(VK_LEFT) & 0x8000f )
cam.yaw(-0.001f);
....
for another 12 keys

i want to test and keystroke with a variable then test the variable to see what it is (in another file). SO how can i do this or is there a better way?


you can catch keypresses from the windows message and pass this to a function, eg

bool keys[256];case WM_KEYDOWN:	// Is A Key Being Held Down?{	keys[wParam] = true;	// Mark key as pressed	return 0;		// Jump Back}


obviously keys can be moved to an input class. You could also have this input class expose the keyboard state through a function that your other files/objects can access. So your input class can grab the keyboard state then the player object or whatever can access the input data.

if you try to make the decisions in your input class you'll find it becoming bloated very quickly, as you end up passing it numerous objects (camera, player, game state...).
3) i have afew globals like below. Also i see this style in dirext tutorials. Is the a problem having such global variables with memory or style ?
I can put all local and pass around but what benefit do i get?

LPDIRECT3D9 g_pD3D = NULL;
LPDIRECT3DDEVICE9 g_pd3dDevice = NULL;
LPDIRECT3DVERTEXBUFFER9 g_pVertexBuffer = NULL;
3) i have afew globals like below. Also i see this style in dirext tutorials. Is the a problem having such global variables with memory or style ?
I can put all local and pass around but what benefit do i get?

LPDIRECT3D9 g_pD3D = NULL;
LPDIRECT3DDEVICE9 g_pd3dDevice = NULL;
LPDIRECT3DVERTEXBUFFER9 g_pVertexBuffer = NULL;
Quote:Original post by jagguy2
3) i have afew globals like below. Also i see this style in dirext tutorials. Is the a problem having such global variables with memory or style ?
I can put all local and pass around but what benefit do i get?

LPDIRECT3D9 g_pD3D = NULL;
LPDIRECT3DDEVICE9 g_pd3dDevice = NULL;
LPDIRECT3DVERTEXBUFFER9 g_pVertexBuffer = NULL;


Well the problem with globals is that they can be modified anywhere, and if you create a bug or memory leak by doing that then good luck tracking them down, it can be difficult. The problem is compounded when you have multiple people working on the same project. Globals are even worse when it is actual data that can change during run time. I think global variables make it impossible to have a threaded program.

If these are set once variables then the issue can be overlooked allthough I would still argue it is bad style. In a true object oriented language it would not even be possible to make a global variable.

A viable solution would be to create a class that manages all of your directx variables, that way you can have as much protection as you want to build in rather than just having them all hang out in the global scope. Instead of a bunch of variables you end up with one global object that can protect its data from the mistakes of a rogue programmer lol.

Edit - I found this post dicussing global variables and thought it had good ideas

Quote:Original post by Fruny
There are a few cases where having a global object makes perfect sense, your is one such. There are, however, a couple of tricks you can do if you dislike 'naked' global variables.

The first is to make it obvious that they are global variables and gather them all in a single "place". Create a namespace called global and put the global variables in it. Or if you are afraid of namespaces, put them in a struct, which will then be your unique global variable. Alternatively, if you are into that kind of perversions, you could borrow from the hungarian notation and prefix your global variables with a g.

Another solution is to hide the global variables behind a function call. Find an implementation of the Singleton pattern(1) and use it for each of the globals, or stick them as static variables in functions (which could very well be member functions and variables of some global class, as a variation on the struct idea). Thinking of it, that is how MFC (rest assured that my interest in that unholy creation is only academic) works, with a single object representing your application.

Finally, you could take the approach that my very own professors advised in their folly, and modify each and every of your functions so that you pass the variables, created in main, down to whatever function needs it. I my not-so-humble opinion, I think this is an horrible solution, as you bear the cost of passing at least one extra parameter down a unknown number of function calls, and can lead to a maintenance nightmare.

1 The Singleton pattern is a technique that ensures that only one instance of a given variable is created. It boils down to encapsulating your pointer into a class as a private static member variable, and providing access to it through a static member function that will call new if the object has not been created in the first place. Articles on that subject can be found online by doing a simple search.



[Edited by - antiquechrono on January 1, 2008 9:52:16 PM]
ok i see your point, and thaks for the article.

I did change my globals and by the looks of it if i have a directx class(for initialization and variables) then that may solve the problem.

q1)What i did try and I since changed was that i had global variables of the same name in 2 .cpp files and i got a linker error. I take it you cant do this?

q2)what about all the win32 initialization code i was wondering what to do with this eg make it a class, namespace,.h file?
Quote:
Original post by Fruny
There are, however, a couple of tricks you can do if you dislike 'naked' global variables.

The first is to make it obvious that they are global variables and gather them all in a single "place". Create a namespace called global and put the global variables in it. Or if you are afraid of namespaces, put them in a struct, which will then be your unique global variable. Alternatively, if you are into that kind of perversions, you could borrow from the hungarian notation and prefix your global variables with a g.


If you follow the first suggestion, you will be putting global variables that have no connection to each other in one place, which kind of reminds me of the traditional C way of writing a huge amount of #defines and global variables at the top of the file when most of them are unrelated, instead of logically grouping them by functionality. I would avoid this idea.

I do however support the idea of prefixing globals with a 'g' because it makes it apparent that they are global (in general I hate this type of prefixing, but globals are one place where I make an exception).

Quote:The Singleton pattern is... Articles on that subject can be found online by doing a simple search.


Of those, this should be the first one you read.
Quote:Original post by jagguy2
ok i see your point, and thaks for the article.

I did change my globals and by the looks of it if i have a directx class(for initialization and variables) then that may solve the problem.

q1)What i did try and I since changed was that i had global variables of the same name in 2 .cpp files and i got a linker error. I take it you cant do this?

q2)what about all the win32 initialization code i was wondering what to do with this eg make it a class, namespace,.h file?


1) No you can not because if the two files are included in such a way that you get a name confilct then the linker will not know which variable to use. Which leads to another reason not to use globals, you run out of useful names lol.

2) Try this Win32 template I found, adapt anything you do not like
http://users.ece.gatech.edu/~lanterma/mpg/direct3dbasics_code.zip
Quote:Original post by Gage64
If you follow the first suggestion, you will be putting global variables that have no connection to each other in one place, which kind of reminds me of the traditional C way of writing a huge amount of #defines and global variables at the top of the file when most of them are unrelated, instead of logically grouping them by functionality. I would avoid this idea.

I do however support the idea of prefixing globals with a 'g' because it makes it apparent that they are global (in general I hate this type of prefixing, but globals are one place where I make an exception).


Err, wha? Placing variables in a namespace doesn't require to place them within the same physical place. You can still group them by functionality, you just add namespacing information around their definition.

Is there a fundamental problem with using
namespace global {   int foo;}
that doesn't also exist when using
int g_foo;
?



This topic is closed to new replies.

Advertisement