0

In my C++ project I have a class called Trap. A Trap is an NPC and an NPC is an Entity. Now I want to loop through all NPC's and do stuff with them. For example, I want a Trap to update. I do that in the following way.

for (vector<NPC>::iterator it = Enemies.begin(); it != Enemies.end(); ++it) {
    it->Update();
}

But now the Update() call is calling the NPC::Update() method.

I'm confident this is because of the way I used the iterator, but I don't know how to better do this. Use a different kind of iteration? Is there a simple trick for this?

Jarod42
  • 203,559
  • 14
  • 181
  • 302
Ozitiho
  • 346
  • 2
  • 9

2 Answers2

4

You have Slicing issue.

Enemies should be std::vector<std::unique_ptr<NPC>> (or other smart pointer) or std::vector<NPC*>

Jarod42
  • 203,559
  • 14
  • 181
  • 302
  • You probably should note that OP should use `std::vector::iterator` or C++11 thing (foreach-loop or `auto` type for it) to handle NPCs. – myaut Feb 26 '15 at 10:46
  • I tried this, but it creates TWO new problems... The first problem is that I'm having trouble iterating through them afterwards. The for loop works just as easily but the following doesn't work. *it->Update();. Secondly, by storing the pointers and not the objects, the NPC's are de-allocated at the end of the stack... I'll have to look into it further. – Ozitiho Feb 26 '15 at 11:36
  • @Ozitiho: I have added samples link (using C++11). – Jarod42 Feb 26 '15 at 11:48
  • You want run-time polymorphism in c++ through inheritance => you must use either pointers (please use smart_pointers in that case) or references. When you store values in std::vector stuff that you put in is sliced to a BaseClass instance. I don't understand you problem with "de-allocated" NPCs. Can you post a more complete example ? We are interested in how you create the objects. – Félix Cantournet Feb 26 '15 at 11:50
  • @Jarod42 Wow, way to go out of your way with those examples. Thanks a ton, that solved all of my problems. – Ozitiho Feb 26 '15 at 12:35
0

What you want is a pure-virtual base class that defines all the basic functions for your derived class. Then you can implement the actual code in your subclasses and still call the update() method through the base class.

class Base
{
    virtual void update() = 0
}

class Implementation: public Base
{
    void update() { /*Do stuff*/ }
}

Next create a vector< unique_ptr<Base> > (whatever pointer type you need) and fill it with new( Implementation ) and you can then loop through your vector and do Base->update().

Jarod42
  • 203,559
  • 14
  • 181
  • 302
Nathilion
  • 309
  • 1
  • 7