2

I am writing a game in C++ which has different enemy types. I have defined a base Enemy class and I also have derived classes enemy1, enemy2 etc. Now for updating these enemies in each iteration of the game, I want to have an array: EnemyArray with its elements pointing to the existing enemies so that I can make sure to update them all with their own version of update(), etc.

One way of doing this, would be to define separate arrays for each enemy type and that would be a clean way of solving the problem. However, I was wondering if the fact that these enemy classes are all derived from the same base class makes it possible to somehow have my EnemyArray as an array of Enemy's and do some modifications later.

0

You can specify base class with virtual function Update and derived classes overriding this function. Here is simple example:

class Enemy
{
public:
    // this is abstract function, but you can also add implementation 
    // as default behavior for derived classes
    virtual void Update() = 0; 
};

class Enemy1 : public Enemy
{
public:
    void Update()
    {
        // update Enemy
    }
}

class Enemy2 : public Enemy
{
    void Update()
    {
        // update Enemy
    }
}

Then create a vector of pointers to base class and fill with objects of specific type:

vector<Enemy*> enemies;
enemies.push_back(new Enemy1());
enemies.push_back(new Enemy2());

And your UpdateAll function can look like this:

void UpdateAll()
{
    for (int i = 0; i < enemies.size(); ++i)
    {
        enemies[i]->Update();
    }
}

Because you are using pointers, don't forget to release all allocated memory at the end of game.

  • "vector<Enemy*> enemies; enemies.push_back(new Enemy1()); enemies.push_back(new Enemy2());" Oh so that would actually work? Aren't the local varriables inside Enemy1 going to increase the size enemies elements need though? And why will I not to use any type-casting or anything? – Maths noob Jul 8 '14 at 14:11
  • Sorry, but I actually don't understand your questions. But I will try to answer: First of all - you don't need any type-casting. This is working. It will call Update method of the right class (because update function is virtual in base class). And local variables in Enemy1 class will increase size of object, but not size of pointer (which is stored in vector). – zacharmarz Jul 9 '14 at 14:42
  • Yeah I was a bit confused. Of course it's just a pointer. I sort of recall VS asking the pointers in an operation to be of the same type, but yeah must have been my immagination. This worked fine! thanks. – Maths noob Jul 9 '14 at 15:44
  • you could always use std::unique_ptr/shared_ptr and forget about managing memory ;) – Abhinav Gauniyal Sep 17 '16 at 7:42
0

(I'm assuming C++)

std::vector holds its elements by value so if you store subclasses you are slicing the objects.

You can use the PImpl idiom to avoid this, you have a concrete Enemy class that holds a (unique) pointer to a concrete enemy an abstract IEnemy that holds the custom code.

class Enemy
{
  Point location;
  std::unique_ptr<IEnemy> pimpl;

  public:
    Enemy(IEnemy&& pimpl): pimpl(pimpl), location(){}

    void onTick(World w){
        pimpl->onTick(w);
    }
}

You can instead hold pointers in you vector std::vector<std::unique_ptr<Enemy>> so it doesn't hold them by value.

  • Ok, I had a read on PImpl pattern and had a look at Pimpl implementation with inheritance: link, but I found that a little tedious. In your purposed method, how are the pointers gonna know what type the derived enemy classes are to call the ? I guess I could add a variable to the base which would determine the type of enemy and give it its value upon calling the constructor for the derived classes, but I find that a bit ugly. Is that what you were suggesting? – Maths noob Jul 8 '14 at 15:17
  • @Mathsnoob make the functions virtual in the IEnemy base class – ratchet freak Jul 8 '14 at 15:42
  • In general the different enemies do different things. Say some do a patrol, and some don't. I guess their recurring routine can all be included in a virtual Update() function, but one can think of cases where that might not be applicable. – Maths noob Jul 8 '14 at 15:46

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.