Чтобы правильно использовать наследование, вы должны сделать что-то вроде этого:
#include <iostream>
#include <vector>
class Fruit
{
public:
virtual void Eat()
{
std::cout << "Mmm.. a fruit!" << std::endl;
}
virtual ~Fruit() {}
};
class Apple : public Fruit
{
public:
void Eat()
{
std::cout << "Mmm.. an apple!" << std::endl;
}
};
class Pear : public Fruit
{
public:
void Eat()
{
std::cout << "Mmm.. a pear!" << std::endl;
}
};
int main()
{
std::vector<Fruit *> fruits;
fruits.push_back(new Pear());
fruits.push_back(new Apple());
fruits.push_back(new Fruit());
for (int i = 0; i < fruits.size(); i++)
fruits[i]->Eat();
return 0;
}
Вам нужно использовать указатели на базовый класс (Fruit *), чтобы использовать преимущества динамической отправки. В противном случае он просто вызовет метод Eat () для Fruit.
Пример в моем ответе позволяет классам, производным от Fruit, переопределять Eat (), если они хотят, но это не обязательно. Если вы делаете виртуальную функцию чистой, то производные классы должны реализовать ее.
class Fruit
{
public:
// Cannot instantiate this class, and derived classes must provide this
virtual void Eat() = 0;
};
Исходя из комментария Донотало, желаемая функциональность может быть реализована следующим образом:
class FruitCollection
{
private:
std::vector<Fruit *> fruits;
public:
void Add(Fruit *fruit);
};
void FruitCollection::Add(Fruit *fruit)
{
fruits.push_back(fruit);
}
В большинстве случаев это, вероятно, излишне, и вам, вероятно, потребуется гораздо больше операций, чем в этом чрезвычайно простом примере.