picklechips
picklechips

Reputation: 804

Derived class object override a function of base class in a vector of objects

so I'm having an issue of calling the override function of a derived class when it's stored in an array of it's base class.

The base class is called Obstacle, and the derived class is Cliff. Obstacle has a virtual function called drawToBackground, and Cliff, which inherits from Obstacle also has a function called drawToBackground, both of which are void.

I then have a vector of Obstacles, called obstsVec. In this vector, I store a bunch of Obstacles and a Cliff. Now say that the cliff is the fifth element of the vector. When I call obstsVec[5].drawToBackground(); it calls the drawToBackground function from the Obstacle class, not the cliff class.

Is this a feature in c++ or might I just have something declared wrong?

Thanks

Upvotes: 2

Views: 2737

Answers (2)

user3116431
user3116431

Reputation: 283

Your classes could look something like:

#include <iostream>
#include <vector>

class Obstacles {
public:
    Obstacles() {};
    virtual void drawToBackground() {
    std::cout << "Obstacle ";
    }
};

class Cliff : public Obstacles {
public:
    Cliff() : Obstacles() {};
    virtual void drawToBackground() {
    std::cout << "Cliff ";
    }
};



int main(int argc, char* argv[]) {
    std::vector<Obstacles*> vec;
    vec.push_back(new Obstacles());
    vec.push_back(new Cliff());
    vec[1]->drawToBackground();
    delete vec[1];
    delete vec[0];
    vec.clear();
}

You mentioned arrays above...make sure never to use arrays polymorphically, as this will lead to undefined behaviour.

Upvotes: 2

Mark Ingram
Mark Ingram

Reputation: 73703

You are storing only the base class in your vector, as @juanchopanza has already mentioned, you have done what is called object slicing. What you need to do is store the objects polymorphically, via a pointer.

std::vector<Obstacle*> myObstacles;
myObstacles.push_back(new Cliff());
myObstacles[0]->drawToBackground();
// Remember to delete when you're done

Of course if you've got access to C++11, then you can forget about the memory management side of things:

std::vector<std::unique_ptr<Obstacle>> myObstacles;
myObstacles.push_back(new Cliff());
for (const auto &obstacle : myObstacles)
{
    obstacle->drawToBackground();
}
// No need to delete anything

Upvotes: 1

Related Questions