Some Newbie C++ Help


Awakening

Active Member
Joined
Mar 5, 2009
Messages
666
Location
Sweden
Website
www.digitalawakening.se
I've not been active in this forum in a long time now, I hope some of you still remember me :) Still waiting patiently for my Pandora to arrive and following PandoraPress through to the wonders of RSS.

I've coded quite a lot in earlier years but never anything as complicated as C++. I'm not coding much these days but there's one project I'm passionate about and keep thinking about and I fiddle around with the code every now and then. I'm learning myself C++ and SDL using the Lazy Foo tutorials. The only way I'm can really enjoy coding is to do it hands on, I plan stuff in my head and get going, learning as I go.

Anyway, to my question. I have a Globals source file and a Globals header file (as suggested by Lazy Foo). Is it just me or is it really annoying to have two almost identical files and keeping them both "updated" all the time? I only have a header file for the constants and they are doing fine. Is there any better way of doing this?
 
What do you keep in the globals.cpp file? If your file is just a lot of constants and/or defines, then i would just drop the cpp file.

That said, you have to get used to having a header file and an implementation file for most things. That is the way c++ works. For defines i usually only have a header file. I am not sure if there is any advantage to having a cpp file to.
 
Some languages (like Java) have 'one place' and its all there, and you specify what is externally visible or not, etc. That makes it 'easy' on one hand, but ugly in another (all your underwear is exposed.) Some languages purely rely on 'reflection' or assumption to work. C++ is fairly explicit, which is 'more work', but I find it a pretty clean approach (in C++, a lot of thigns are ugly, but I find the separation of visibility pretty good :) -- you lay out very carefulyl what is visible using headers, and the rest of it is hidden. (That said, once you get to inlines and such, its all goofy again :)

There are tricks you can do such as using #define macros so that in the header, the critters are declared, but in the implementation, they are instanciated. There are many ways to do that .. remembering that globals are set to 0/NULL by default, so the only real declarative difference to simple globals is 'extern' at the front (and some compilers will even 'assume' that for headers, which is icky.) So you could easily have a #define that sets up an EXTERN macro, which you then put at the front of every declaration, or something. But in the end, I find all that fidgeiting around, its easier to just do it.

Recall aslo that if you're passing so much around in globals that you need a lot of globals visible, you might be doing something 'wrong'; maybe you want to have a config hash table, or config linked list, or something as your state instead. Or maybe you want one .h that defines MYState.h, with a struct MYState, which has it all in it; and then your C code just is mallocing or new()ing one instance of that, and handing it around.. so the entire declaration is in one header, and the users of it just get a pointer to it (or a reference), or do a new() on it.

Having long lists of ..

int foo = 0;
int baz = 10;
...
etc

And then a header to let other files peek at that, is probably not the best way to do it.

That said, the criticism does hold somewhat for functions; if a .cpp file has 2000 functions in it, somewhere out there wll be .h files with the class/member/function declarations, and of course you have to keep them all in sync. But again, extra 'typing', but I'd say having the public skelewton of the class declaration and the private underpants of the class in separate places is good for documentation. (And most peopel are using IDE's anyway, especially with highly verbose languages like java or even c++).

jeff
 
Kinda violates the whole OO thing, but if you are really lazy, you can place method impls in header files as static methods for utility/manager type classes. :)

example inside a SDLHelperUtils.h

Code:
class SDLHelperUtils {

    public:

        static void decorate(DecoratedSurface *surface) {
            surface->surface = SDLHelperUtils::load_img(surface->rel_file_path);
        }
};

EDIT: forgot the code tags.
 
Oh, that's a lot of words I do not yet understand :) Well, I do not have a lot of global variables, nor do I plan to. I just find this really annoying. At least at this stage where I might just throw in a global variable to test something out, I'm very likely to forget to add it to the header.


This is basically what my Globals.cpp file looks like right now:
Code:
#include "SDL/SDL.h"
#include "globals.h"

SDL_Surface *screen = NULL;
SDL_Surface *box = NULL;
...



And Globals.h looks like:
Code:
#ifndef GLOBALS_H
#define GLOBALS_H

#include "SDL/SDL.h"

//The surfaces
extern SDL_Surface *screen;
extern SDL_Surface *box;
...
#endif
 
But you could do it like this ..

class MyGlobals {
public:
int m_crazy;
int GetFoo() { return m_foo; }
int SetFoo ( int x ) { int y = m_foo; m_foo = x; return y' }
void MyGlobals ( void ) { m_foo = 37; // default }
private:
int m_foo;
};

then you would just do this, once, say at the beginning of main():

MyGlobals globals;

In another file, you just use:

extern MyGlobals globals;

Then you could refer to globals.m_crazy if you want no protection, or use get/setters with globals.GetGoo() for a nice abstraction layer.

1) The class is all in one place, no having separate impl/decl since you do inline functions/constructors
2) You have as much control as you like

(1) is debatable .. by making it 'easy on yourself', you're also showing everythign about your class to anyone who casually looks; if you make it implementation and declaration as separate entities, then peopel can see the interface, without seeing how it all works 'more or less'. Itrs up to you.

There are other ways, as well (using hash tables or linked lists, or something like a 'settings' class).

A settings class is always fun -- a class with 'get' and 'set' and 'save' and 'load' (among others); Instead of 'hard coding' the various globals, they're dynamic .. just use myconfig.set ( 'myvar', myvalue ), and you're done, itds created as you need it. Then you have multoiple set() functions in the settings class, to handle each kind of type.. or use a Template if you want to get nutty. Further, then you can just call myconfig.save ( filename ) and poof, all written out your settings. And to get nuttier still, use a iostream or some streaming object as a save/load target, and poof, you can suddenly load from disk, or from a http URL on the web, without changing your code.

Its all just a matter of how insane you want to get.

It doesn't have to be ugly or typey :)

jeff
 
Thanks skeezix :)

I think for now I'm just going to keep things as is, seems a lot easier and cleaner :D

However, I need to learn how to code my own settings class later as that's something that will be useful down the line.
 
Back
Top