Хранение объектов разных типов

220
12 апреля 2018, 13:22

Есть абстрактный класс "Organism". Его наследуют 2 классa: "Animals" и "Plants"

Как образом можно хранить объекты классов "Animals" и "Plants" в 1 массиве\векторе\чём-либо ещё

Answer 1

Так как речь идёт скорее всего о компьютерной игре, а класс Animals и Plants будут представлены как объекты управления, то лучше всего использовать фабрику паттернов, для создания самих объектов, а их указатели хранить в std::list или std::forward_list, так как скорость вставки и удаления( рождение, смерть) элемента будет константной.

Answer 2
#include <iostream>
#include <vector>
#include <memory>
using namespace std;
// Вначале объявим базовый класс
class Organism {
public:
  virtual string name() = 0;
  virtual ~Organism() = default;
};
// наследники
class Animal : public Organism
{
  public:
    string name() override { return "Animal"; }
};
class Plant: public Organism
{
  public:
    string name() override { return "Plant"; }
};

int main() {
    // так как на дворе 2018, то пишем на 11 стандарте и используем умные указатели
    vector<unique_ptr<Organism>> org;
    // и добавление без new
    org.push_back(make_unique<Plant>());
    org.push_back(make_unique<Animal>());
    // а вот здесь объязательно нужно const и &, так как unique_ptr
    for (const auto& o : org) {
        // name - виртуальная, поэтому никаких dynamic_cast
        cout << o->name() << endl;
    }
    // и память за нас компилятор освободит.
    return 0;
}

Возможно, в будущем, нужно будет unique_ptr заменить на shared_ptr.

Или это все таки школьная задача и преподаватель будет компилировать в turbo c++ 3?

Answer 3
// Создадим массив и добавим в него одно животное и два растения:
std::vector<Organism*> mas;
mas.push_back(new Plant);
mas.push_back(new Animal);
mas.push_back(new Plant);
// Узнаем, то, что лежит ли в mas[1] это растение или животное:
if (dynamic_cast<Plant*>(mas[1]))
{
    std::cout << "this is Plant" << std::endl;
}
else if (dynamic_cast<Animal*>(mas[1]))
{
    std::cout << "this is Animal" << std::endl;
}
else
{
    std::cout << "this is unknown Organism" << std::endl;
}
// Удаление:
for (int i = 0; i < mas.size(); ++i)
{
    delete mas[i];
}
mas.clear();
// Если всё было сделано верно, и деструктор класса Organism был объявлен как виртуальный, то delete вызовет правильный деструктор и утечки памяти не будет
READ ALSO
как можно создавать массив из значения в обьекте

как можно создавать массив из значения в обьекте

как можно получить новый массив состоящий из name например["dima", "Anna", "Denis"], и отдельный массив из lang ["javascript", "php", "html", "css", "python", "ruby"], пробовал через...

159
Не работает browser sync

Не работает browser sync

ЗдравствуйтеНе могу разобраться никак, что не так? Все запускается при сохранении пишет Reloading Browsers, но не обновляет!

219
Не находить id с строки get запроса node(express)

Не находить id с строки get запроса node(express)

Привет!Я хотел сделать свой небольшой API сервер на NODEjs но столкнулся с проблемой что сервер не видит переменную id с строки запроса и я постоянно...

170
JavaScript прервать setInterval не замораживая страницу

JavaScript прервать setInterval не замораживая страницу

Есть ли удобный способ прервать setInterval на определенное время, не замораживая при этом страницу? Важно потом продолжить выполнение setInterval

173