C++ - a class, a void* and a new object

Started by
12 comments, last by Pacifist 18 years, 11 months ago
I have a function in a class like so (this is a trivial example but my real project has a purpose for the void pointers)
bool Monster::DataResponse( int messageType, void *messageValue )
{
  // return units x and y position in the messageValue pointer
  point *unitPosition = new point; // ToDo: delete
  point->x = xPos;
  point->y = yPos;
  messageValue = (void*)point;
  return true;
}
Now when the program calls this DataResponse function from another class and casts the messageValue back into a point the x and y values are not what is expected Why?
My games: www.spiralfast.com/pacifist
Advertisement
There are better ways to do this, but the direct answer to your question is that you aren't storing anything into messageValue. You would need something like this, instead:

bool Monster::DataResponse( int messageType, void **messageValue ) // note the '**' (pass in the address of messageValue){    // return units x and y position in the messageValue pointer    point *unitPosition = new point; // ToDo: delete    point->x = xPos;    point->y = yPos;    *messageValue = (void*)point; // note the '*' (store point at the address pointed to by messageValue)    return true;}

"void *messageValue" should be passed as "(void*) &messageValue" or "void **messageValue"
Pass a reference: void *&messageValue. Otherwise you're just changing a copy; the original pointer that the calling code used is still the old value.

Also, what is this purpose for the void pointers? I don't believe you.
Chess is played by three people. Two people play the game; the third provides moral support for the pawns. The object of the game is to kill your opponent by flinging captured pieces at his head. Since the only piece that can be killed is a pawn, the two armies agree to meet in a pawn-infested area (or even a pawn shop) and kill as many pawns as possible in the crossfire. If the game goes on for an hour, one player may legally attempt to gouge out the other player's eyes with his King.
Quote:Original post by smart_idiot
Also, what is this purpose for the void pointers? I don't believe you.


In case he wanted to do something like this [grin] Hides in corner
Or my heterogeneous untemplated [well, sort of templated] linked list class *ducks*

OH, you mean good purpose...
Thanks all i got it.

Quote:Original post by smart_idiot
Also, what is this purpose for the void pointers? I don't believe you.


I need to pass data back to the parent class but that data is different for every monster.

ie. all game objects derive from a base class (funnily enough called GameObjectBase)

This has common functions like Draw (all game objects are renderable in this game) and Animate (steps forwards a frame). All the derived game objects are stored in a vector so i can just call (psuedocode)
for all elements of the vector{  Animate  Draw}



Now there comes the problem of input, some objects respond to keyboard input some only to mouse some to both and most objects return data that is valid only to them (the hero for example returns a display inventory message along with a pointer to his inventory when clicked).
I want to make the game so that when i get a mouse click i can go

messageType = MOUSE_CLICK;messageValue = point;for all elements of the vector{  if ( object.DataResponse( &messageType , messageValue ) // true if object was the one clicked  {    if ( messageValue != NULL )      processResponse( &messageType , messageValue ); // a function that does the returned request    break;  }}


That way all objects can still inherit the one base class (easier for rendering) despite the differences in the way they respond to the different types of input.



If you can think of a better way of doing this without voids then tell me :)

Edit: my topmost example should have had int *messageType as a parameter so that i can pass a different messageType back again.

[Edited by - Pacifist on April 26, 2005 10:08:02 PM]
My games: www.spiralfast.com/pacifist
ewww...

I use functors for this. [though ironically enough, the functor class I've used for all my gui-stuff in the past stores the parameters in the void* heterogeneous semi-templated linked list class....]

Essentially...

[though please please someone correct me if the STL adapaters allow for better functor goodness...]

[and sorry for the length; I need the practice]

struct action{     void    operator()()=0;     virtual ~action(){}};template <typename T>struct global_action:public action{     T      t;     void    operator()(){            t();     }     global_action(T &some_action):t(some_action){}};template <typename F>action    *make_global_action(F f){     return(global_action<F>(f));}struct keybinding{     keycode   key;    // define keycodes somewhere...     action    *bound_action;     void      activate(){            if (bound_action){                  (*bound_action)();            }     }     bool      match(keycode k){            if (k==key){                 return(true);            }else{                 return(false);            }     }     keybinding(keycode k, action *inaction):key(k),bound_action(inaction){}     ~keybinding(){delete bound_action;}};   // And similar for mousetargets!          struct GameObjectBase{     vector<keybinding>      kbinput;         // or, use a fixed array or map                                              //  if you expect this to be                                               //  usually full.     mouse_target            onleftclick;     mouse_target            onrightclick;     virtual void            animate();     virtual void            render();     // stuff!};


Then, you just need to figure out which object takes the input, and activate the bound functor. For the hero example, the hero should post the message "open hero_inventory here" [to a queue where it's later picked up] from the bound function, not return it.

In the way I've done it in the past that is...

Eh. That's a terrible example. Something like that...
I'm reading up on functors now although it seems way more complex than the way i do it.

My way i have all game objects in a vector which is inside the main game class.
Then i send the mouse events to all those objects to find what object was clicked.

Then if the object returned a message such as SHOW_INVENTORY in messageType i create a new InventoryDisplay object in that vector with messageValue(a void*) pointing to the inventory items.
However if the object returned a message such as SHOW_STATS in messageType i create a new StatsDisplay object with messageValue pointing to the stats.

See the above stuff is my problem, the objects themselves are the ones that decide what to request/return if they have been clicked. The hero doesn't always return show inventory on a mouse click and a monster doesn't always return show stats on a mouse click. If the monster is dead for example i'd prefer the monster to display an inventory screen rather than a stats screen when he is clicked, with my way he can easily do this.

So i can't really bind an open inventory function to the hero object, the hero object itself needs to determine what to request from the main class in the returned values.

Anon was me btw :p
My games: www.spiralfast.com/pacifist

This topic is closed to new replies.

Advertisement