Что я делаю?
Я пытаюсь сделать базовое наследование для игры, над которой работаю. Идея состоит в том, чтобы иметь базовый класс Entity, от которого наследуется Player. Класс Entity имеет виртуальный метод update или think, который каждый дочерний элемент переопределяет в соответствии со своими потребностями.
Вот как движок обрабатывает цикл обновления:
void Engine::update() {
for (Entity entity : entities) {
entity.update(deltaTime);
}
}
Код:
Entity.hpp
#pragma once
#include "Position.hpp"
#include "AssetManager.hpp"
#include "Logger.hpp"
#define SPATIAL 1
#define VISUAL 1 << 1
class Entity {
public:
Entity(Position *position, const char *visualPath);
int flags;
const char *visualPath;
Position position;
virtual void update(float deltaTime);
};
Entity.cpp
#include "Entity.hpp"
Entity::Entity(Position *position, const char *visualPath) {
flags = 0;
if (position) {
flags |= SPATIAL;
this->position = *position;
}
if (visualPath) {
flags |= VISUAL;
this->visualPath = visualPath;
}
}
void Entity::update(float deltaTime){
Logger::log("No update method");
};
Player.hpp
#pragma once
#include "../Entity.hpp"
#include "../Logger.hpp"
class Player : public Entity {
public:
Player();
void update(float deltaTime) override;
};
Player.cpp
#include "Player.hpp"
Player::Player() : Entity(new Position(0, 0), "assets/player.png") {}
void Player::update(float deltaTime) {
this->position.x += 10;
Logger::log("Player says hi");
}
В чем проблема?
Несмотря на то, что я переопределил метод обновления для Entity
внутри Player
, Player
по-прежнему печатает "Нет способа обновления". Кажется, переопределение ничего не сделало.
Tangential: #define VISUAL 1 << 1
вас удивит, если вы ожидаете, что это всегда будет означать 2
. Например, попробуйте std::cout << VISUAL;
. Рассмотрите возможность использования настоящих constexpr
переменных.
Измените это:
void Engine::update() {
for (Entity entity : entities) {
entity.update(deltaTime);
}
}
К этому:
void Engine::update() {
for (Entity& entity : entities) {
entity.update(deltaTime);
}
}
В исходной реализации ваш цикл for
создает копировать элемента в сущностях. Возможно, вы этого не хотели, но что более важно, entity
— это просто копия базового класса, поэтому информация о производном классе теряется. Передавайте по ссылке, чтобы избежать этой проблемы и других ошибок.
Entity entity : entities
Нарезанный. Вы, вероятно, хотитеEntity &entity : entities
, но у вас, вероятно, есть аналогичная проблема дальше по цепочке, когдаentities
не сохраняет ссылки на производные классы.