Reputation: 804
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
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
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