Полиморфизм - правильное использование указателя на чистый абстрактный класс? - PullRequest
1 голос
/ 21 ноября 2011

Я реализую простую настольную игру (Прорыв) с использованием OpenGL (плюс GLUT и GLUI).

Я думаю о реализации класса Board, у которого vector<vector<Cell> > будет одним из его атрибутов. Cell представляет пробел в игровом поле. Может содержать GameObject. GameObject будет чисто абстрактным классом. Он требует, чтобы его производные классы реализовали, например, render(). Возможные производные классы будут:

  • Blank, представляющий пустое пространство
  • Pawn, представляющий пешку (единственно возможные фигуры в Прорыве)

Доска будет обработана, сначала отрисовав доску, затем итеративно просматривая каждый Cell, получая его содержимое и вызывая render() для каждого из них.

Единственный возможный способ достижения этого - сделать указатель GameObject в Cell (board[y][x].getContents()->render(), где getContents() возвращает GameObject*)

Это лучший способ сделать это? Это правильное использование указателей?

Ответы [ 2 ]

3 голосов
/ 21 ноября 2011

Позвольте мне превратить мой комментарий в ответ.Это не означает, что он в каком-то смысле завершен, только то, что это позволяет мне разобрать некоторые примеры кода.Мой первоначальный комментарий:

Это нормально, хотя вам, вероятно, лучше справиться с std::unique_ptr<GameObject> или std::shared_ptr<GameObject>, чтобы вы не заблудились среди проблем, связанных с ручным управлением временем жизни.Наконец, как насчет плоского 1-D массива, доступного по шагам?

Вот как я могу это сделать:

#include <vector>
#include <memory>

struct GameObject { virtual void render() const = 0; virtual ~GameObject() { } };

class Cell
{
  std::unique_ptr<GameObject> m_go;

public:
  void render() const { m_go->render(); }
  Cell() : m_go(new BlankCell) { }
  // more functions to reassign the cell value etc.
};

class Board
{
  std::vector<Cell> m_board;
  std::size_t       m_length;

public:
  Board(std::size_t length) : m_board(length * length), m_length(length) { }
  Cell & cell(std::size_t i, std::size_t j) { return m_board(j + i * m_length); }
  Cell const & cell(std::size_t i, std::size_t j) const { return const_cast<Board*>(this)->cell(i, j); }
  // more...
}
2 голосов
/ 21 ноября 2011

Да.

Также, возможно, вам следует использовать другой контейнер для ваших ячеек (какой-то вид матрицы или около того)

...