Shi Yi Lee
Shi Yi Lee

Reputation: 37

Pointer of class to void*

i am working on a rpg games with class i created a struct call Character with ActionList* which store the instance. GeneralPlayer is a class where there have still a bunch of other players classes inherited it. This is my header file:

class Battle
{
public:
       struct Character
      {
        char type;//monster or player?
        bool alive;
        void*instance;//pointer to instance
      };
      Battle(GeneralPlayer*,AbstractMonster*,int,int,int);     
      Battle(GeneralPlayer*, AbstractMonster*, int, int);
private:
       Character *ActionList;
};

i was trying to convert GeneralPlayer* to void*. However seems like the code doesnt work as i thought. P and M are array of pointers of those player classes.

 Battle::Battle(GeneralPlayer*P, AbstractMonster*M, int a, int b, int c)
{
   a = numP;
   b = numM;
   c = turn_limit;
   ActionList = new Character[numP + numM];
   P = new GeneralPlayer[numP];
   for (int i = 0; i < numP; i++)
   { 
      ActionList[i] = static_cast<void*>(P[i]);
      ActionList[i].type = 'p';
   }
  for (int i = numP; i < numP+numM; i++)
  {
      ActionList[i] = static_cast<void*>(M[i]);
      ActionList[i].type = 'm';
  }
}

it keeps showing the error C2440. I wish can solve my problem with anyone helps thank you.

Upvotes: 0

Views: 622

Answers (2)

Some programmer dude
Some programmer dude

Reputation: 409156

One of the problems here is that the Character structure is not a parent of either GenericPlayer or AbstractMonster. It seems that the Character::instance member should be pointing to the player or monster, which means your code should be something like

ActionList[i].type = 'p';
ActionList[i].alive = true;
ActionList[i].instance = &P[i];

This is assuming that the list of players is already initialized by the caller of the Battle constructor, then you should not allocate a new array of players, so the P = new GenericPlayer[numP]; statement should be removed.

It should be noted that having something like you do, a "generic pointer" (what void * is) and then a member saying what type it's really pointing to is considered bad design. Instead you would have a common base-class for both monsters and players, and use a pointer to that. Then with the correct use of polymorphism and virtual member functions you don't need the type field. And then it's easy to refactor the code to use some other means of telling if a player or monster is alive or not, and then you don't need the Battle::Character class at all, and could use an array of pointers to the common base class instead, thus simplifying the code a bit, which is very good for maintainability.


There are a few other problems with the code as you show it, things that will cause problems later at runtime.

One problem is that in the loop iterating over the monsters, you initialize o to numP and loop up to numP + numM, but if the array M doesn't contain numP + numM elements you will go out of bounds.

Instead I suggest you do e.g.

for (int i = 0; i < numM; i++)
{ 
    ActionList[i + numP].type = 'm';
    ActionList[i + numP].alive = true;
    ActionList[i + numP].instance = &M[i];
}

Upvotes: 4

Sven Nilsson
Sven Nilsson

Reputation: 1869

You are trying to convert object into pointer, use the & operator to get the pointer in question.

ActionList[i] = (void*)&P[i];
ActionList[i] = (void*)&M[i];

Upvotes: 5

Related Questions