Как правильно организовать взаимодействия объектов в игре, что бы не нужно было узнавать тип объекта(с++, ООП)?

У меня есть класс LevelLoader. Он возвращает вектор объектов BaseObject
Я передаю его в GameField.

Игрок побеждает, тогда, когда в GameField не остается ни одной Point.
Но как мне это определять?

Первое что приходит в голово - при добавлении объектов в GameField, проверяем, если добавляем Point, то увеличиваем pointsCount на 1 (с уменьшением при удалении Point проблем нет).

Но проверять тип объектов - это очень не хорошо. Поэтому нужно как-то по-другому.

Может быть лучше считать количество созданных точек в LevelLoader и передавать в GameField? Но это тоже не кажется лучшим решением.

p.s. ну и static поле в Point - тоже не вариант в принципе, так как меня интересует количество точек в GameField, а не вообще (хоть в практически всегда оно и будет совпадать).
  • Вопрос задан
  • 85 просмотров
Пригласить эксперта
Ответы на вопрос 1
@d0lph1n
Не вижу красивого решения, подходящего под Ваши ограничения. Мне кажется, можно добавить дополнительную абстракцию: BaseObject <- BasePoint <- Point, а в GameField из LevelLoader передавать не массив BaseObject'ов, а контейнер (назовем его Level, например), который содержит Ваши точки и прочие игровые объекты в отдельных структурах данных.

С другой стороны, если у Вас GameField - это доска для игры в ГО, на которой всего-то и есть, что черные точки да белые точки, тогда вовсе нет смысла создавать BaseObject. Задача больше похожа на архитектурную, чем на техническую, и решать ее будет удобнее, если Вы подробнее опишете задумку.

UPD. p. s. От "грязных" трюков совсем уж отказываться не стоит, особенно если приперло. В Qt, например, реализован механизм определения типа, и это не костыль, а жизненно важная фича для реализации концепции управления объектами. А в Java так и вовсе существует т. н. "рефлексия", что подразумевает не только способ определить имя класса, но и получить информацию о его методах и атрибутах. Казалось бы, какая гадость! Но ведь работает.

UPD2: Не знаю, актуально это еще для Вас или нет, но я наткнулся вот на какой трюк в Книге "Эккель - Философия C++, часть вторая", страница 234.

template <class t>
class base {
    static int sn_objects;
public:
    base() {
        sn_objects++;
    }
    ~base() {
        sn_objects--;
    }
    static int count() {
        return sn_objects;
    }
};

template<class t> int base<t>::sn_objects = 0;

class daughter : public base<daughter> {};
class son : public base<son> {};

int main(int argc, char** argv) {
    daughter d1;
    daughter d2;
    daughter d3;
    son s1;
    std::cout << daughter::count() << std::endl; // --------- 3 ---------
    std::cout << son::count() << std::endl; <b>   // --------- 1 ---------

    return 0;
}


Однако в этом случае мы не сможем посчитать все объекты, унаследованные от base. Только если мы base унаследуем от какого-нибудь другого класса, где будем считать статические переменные по-старинке:

#include <iostream>

class the_very_base {
    static int sn_common_counter;
public:
    the_very_base() {
        sn_common_counter++;
    }
    ~the_very_base() {
        sn_common_counter--;
    }
    static int count_all() {
        return sn_common_counter;
    }
};
int the_very_base::sn_common_counter = 0;

template <class t>
class base : public the_very_base {
    static int sn_objects;
public:
    base() {
        sn_objects++;
    }
    ~base() {
        sn_objects--;
    }
    static int count() {
        return sn_objects;
    }
};

template<class t> int base<t>::sn_objects = 0;

class daughter : public base<daughter> {};
class son : public base<son> {};

int main(int argc, char** argv) {
    daughter d1;
    daughter d2;
    daughter d3;
    son s1;
    std::cout << daughter::count() << std::endl;              // --------- 3 ---------
    std::cout << son::count() << std::endl;                       // --------- 1 ---------
    std::cout << the_very_base::count_all() << std::endl; // --------- 4 ---------

    return 0;
}


Основано, разумеется, на статических переменных, но только в самом исходном коде статическая переменная всего одна - не приходится объявлять их по 10 штук.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы
от 50 000 до 80 000 руб.
ProfitClicks Краснодар
от 100 000 до 150 000 руб.
Migo group Волгоград
от 16 000 до 25 000 руб.
20 марта 2019, в 01:07
1000 руб./за проект
20 марта 2019, в 00:27
2000 руб./за проект
19 марта 2019, в 23:14
6000 руб./за проект