• 10
• 10
• 12
• 12
• 14

# How can I create a sort of message object?

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

## Recommended Posts

Hellos! I am writing a game using C++, using DevC and Allegro. I'm very into the OOP approach and generally understand it very well. I have my main() and it creates objects for sprites, the game map etc. All well and good. I am stuck though with one thing. I want to create a class to help me test other classes, maybe called something like Message, that displays text on the screen. Other classes should be able to send messages to it, showing the contents of variables or whatever. eg if my sprite class creates 20 sprites it should be able to send the string "20 sprites created" to the Message object, which will then display the information on the screen. The problem is, how do I create a class that can be accessed by any other class in my program? Or am I being totally dumb in this approach?

##### Share on other sites
Check out Singletons.

##### Share on other sites
Have a global stream class.

Try this:-

// stream classclass CMessageLogger {public:    CMessageLogger( void )    {    }    ~CMessageLogger( void )    {    }    // this outputs a message    operator << ( const char* str )    {        // output the string        DrawText( 10, 10, str ); // or whatever function you use to output your text    } // end operator <<}; // end class CMessageLogger

You would use it like this:-

// create 10 spritesfor ( int i = 0; i < 10; i++ ){    // create the sprite    if ( CreateSprite( AppendString( "SpriteName%d", i ), AppendString( "%d.bmp", i ) ) == E_FAIL )        g_MessageLogger << AppendString( "Failed to create sprite %d", i );} // end for

Mmm, that AppendString function actually sounds quite good. I think I'll make one...

I hope this helps.

##### Share on other sites
This is what I was trying to do - a simple global class that can store and display the messages. I thought I was doing something wrong, but then I tried just creating an ordinary global variable, a very simple thing, even then I get compile errors when I try to access it in any of my classes.

Tell me if I'm doing something wrong here...

In my main.cpp file, just after the #include stuff, and just before main(), I delcare a global integer like this:

#include etc etc etc

int testglobal;

int main()
{
etc etc etc

That's correct isn't it? The correct way to declare a simple global integer.

But then, when I try to access it from within a class method I get an error. For example in my file called test.cpp I simply put:

#include "test.h"

void Test::Note()
{
testglobal=20;
etc etc

All I'm doing is trying to access the variable from within a class method. Surely the fact that it's global means it should be straightforward to access?

But I get this error:

'testglobal' undeclared (first use in this function)

Any ideas???
Something wrong with my header files?

##### Share on other sites
Something's wrong with your source file organization. Check out the bit about keyword 'extern', in particular.

As for the code design, simple globals work fine, perhaps wrapped in their own namespace - a class doesn't gain you anything except worrying about whether or not to add extra code to control the instance creation/lifetimes. Just be sure to follow the usual principles of encapsulation:

// GlobalInterface.h#ifdef GLOBAL_INTERFACE_H#include GLOBAL_INTERFACE_Hint bar(int);extern int baz; // "public"#endif// GlobalInterface.cpp#include "GlobalInterface.h"int baz = 3; // the actual instance referred to by the extern// As with class design, you should try really hard to avoid "public data"int quux = 2; // "private" - not referred to in headerint bar(int wibble) {  return quux *= wibble;}// and you can similarly make private "helper" functions, too// main.cpp#include "GlobalInterface.h"int main() {  cout << bar(3) << endl; // ok  baz = 42; // ok  //quux = 12; <-- error, 'quux' undeclared in this translation unit}

This is how data hiding and encapsulation used to be acheived in C, before all this fancy OO stuff came along. Don't get me wrong, I like OO and think in it rather naturally, but it's not always the most logical thing - and these techniques are important too. (In C, one also often invokes the dread "void *", for reasons of additional data hiding, as well as "polymorphism" acheived by manual type inspection and pointer casting magic. Please don't do that in C++.)

Unfortunately I can't tell you offhand exactly how to make that work with namespaces thrown in, but I'm sure you can figure it out with a bit of trial and error :)

##### Share on other sites
Quote:
 Original post by joebarnslondonBut I get this error:'testglobal' undeclared (first use in this function)Any ideas???Something wrong with my header files?

You need to declare the variable in the header file with the 'extern' keyword.

So in test.h you would have this line:-

extern int g_nVar;

In main.cpp file you would have the line:-

int g_nVar;

Make sure that main.cpp includes test.h otherwise it won't share that variable with any other cpp files that declare it.

##### Share on other sites
OK, thanks, that's cool, I've played around and got the hang of the extern keyword now.

It seems weird to have to do that stuff though. Like, it seems weird that compilers aren't intuitive enough to look through all your files and work these things out. I guess in reality they could be designed that way but if they were it would take longer to compile (certainly if you had a really vast project it would become a problem).

I just read somewhere that you can get round the problem by declaring all your globals in a header file maybe called globals.h then including it in all your class files or something. (OK, it may be bad practice to have globals but that's a different story, and they are useful some times especially for simple temporary testing and experimenting.)

##### Share on other sites
The reason that you need the extern keyword is because C/C++ has a vast variable scope methodology. For instance, you may want in foo.cpp a global variable called g_nBar and in test.cpp a global variable also called g_nBar and for these two variables to be treated differently. Now if the compiler looked through all of the files and found these two variables and treated them the same, you would not get the desired result. But if you did want those two variables to be treated the same, then the extern keyword comes into play.

There is nothing wrong with using global variables when they are needed. For instance, if there is an extremely common variable such as your graphics object, you would not want to continually pass that around in functions. The easer method of distributing this variable would be by making it global. You should look into singletons, as these are like global variables, but cleaner and a lot safer.

##### Share on other sites
Is that how people do graphics for games generally, as singletons?

##### Share on other sites
I don't use singletons for graphics, but I'm sure some people do. My normal method looks something like this:
Renderer   | - PolygonRenderer  (etc)Renderable   | - Polygon  (etc)Vertex2DVertex3D
Then you would use it like this:
Polygon polygon;polygon.addVertex(Vertex3D(/* etc */));// More calls to polygon.addVertexRenderer* renderer = polygon.getRenderer();renderer->render(polygon);
If someone can think of a better method, please let me know. [smile]