Вызов функций производного класса из вектора (c ++) - PullRequest
4 голосов
/ 11 марта 2011

У меня есть два класса:

class Object {
public:
  Object();
  virtual void update();
  virtual void draw();

private:

protected:
  int x, y, tick;

}

и

class Unit : public Object {
public:
  Unit();
  void update();

private:

protected:

}

Затем я определяю конструкторы и функции в отдельных файлах .cpp.

Вот определения дляОбъект:

Object::Object() {
  x = y = 0;
};

Object::update() {
  tick ++;
};

Object::draw() {
  // All my draw code is in here.
};

И Единица измерения:

Unit::Unit() : Object() {

};

Unit::update() {
  Object::update();
  // Then there's a bunch of movement related code here.
};

Все работает по отдельности, но я сталкиваюсь с проблемой при попытке вызвать функции из вектора.

vector<Object> objects;

Затем я делаю это в моем void main ():

for (int i = 0; i < objects.size(); i ++) {
  objects[i].update();
  objects[i].draw();
};

Это прекрасно все отрисовывает, но вызывает только объектную версию update (), а не версию, определенную производным классом.Нужно ли создавать вектор для каждого типа, который я извлекаю из класса Object, чтобы он работал, или есть другой способ вызова производных функций?

Заранее спасибо - Сеймор

Ответы [ 2 ]

6 голосов
/ 11 марта 2011

Да, он вызывает методы class Object, потому что у вас есть вектор class Object объектов:

vector<Object> objects; // stores instances of class Object

Возможное решение - использовать вектор указателей:

vector<Object*> objects;
objects.push_back( new Unit() );

и затем вызывать указатели:

for (int i = 0; i < objects.size(); i ++) {
    objects[i]->update();
    objects[i]->draw();
}
2 голосов
/ 11 марта 2011

Если вы хотите использовать объектно-ориентированный полиморфизм в C ++ (что означает: у вас есть базовый класс и производные классы, и во время выполнения вы можете столкнуться с любым из них), вы должны использовать указатели.

vector<Object *> objects;

Это означает ручное управление памятью (но вы можете использовать shared_pointers или http://www.boost.org/doc/libs/1_35_0/libs/ptr_container/doc/ptr_container.html), и, возможно, очень небольшую потерю производительности (из-за одной дополнительной разыменования и v-таблицы, однако вам на самом деле это не нужно).не забудьте сделать ваши методы виртуальными;)

Я думаю, именно поэтому я редко использую в своей повседневной работе объектно-ориентированное программирование, как я изучал его в школе;) Я использую наследие, но не смешиваю матьи дочерние классы в тех же контейнерах (и я использую шаблоны для многих интерфейсов).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...