0

What am I doing?

I'm trying to do some basic inheritance for the game I'm working on. The idea is to have a base Entity class that the Player will inherit from. The Entity class has a virtual update or think method that each child will override to fit it's needs.

This is how the engine handles the update loop:

void Engine::update() {
  for (Entity entity : entities) {
    entity.update(deltaTime);
  }
}

The code:

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");
}

What's the issue?

Even tho I have overridden the update method on the Entity within Player, Player still prints "No update method". It seems the override didn't do anything.

  • 1
    `Entity entity : entities` [Sliced](https://stackoverflow.com/questions/274626/what-is-object-slicing). You probably want `Entity &entity : entities`, but you likely have a similar problem further up the chain with `entities` not storing references to the derived classes. – user4581301 May 03 '22 at 20:30
  • 1
    Tangential: `#define VISUAL 1 << 1` is going to surprise you if you expect that to always mean `2`. For instance, try `std::cout << VISUAL;`. Consider using genuine `constexpr` variables. – Nathan Pierson May 03 '22 at 20:38

1 Answers1

2

Change this:

void Engine::update() {
  for (Entity entity : entities) {
    entity.update(deltaTime);
  }
}

To this:

void Engine::update() {
  for (Entity& entity : entities) {
    entity.update(deltaTime);
  }
}

In the original implementation, your for loop makes a copy of the item in entities. You probably didn't want that, but more importantly, entity is just a copy of the base class, so the derived class information is lost. Pass by reference to avoid this issue and other bugs.

Ted Bigham
  • 4,237
  • 1
  • 26
  • 31
selbie
  • 100,020
  • 15
  • 103
  • 173