2

I am making an Entity class for my sfml game but I can't understand why the following code can't compile. I get an undefined reference to vtable in Entity error.

Here is the header file:

#ifndef ENTITY_H
#define ENTITY_H
#include <string>
#include <SFML/System/Vector2.hpp>
#include <SFML/Graphics/Rect.hpp>
#include <SFML/System/Time.hpp>

class Entity
{
public:
        Entity(std::string id, sf::Vector2f position, float rotation );
        virtual ~Entity() = 0;
        virtual sf::FloatRect getBoundingRect() const;
        virtual float getRadius() const;
        void UpdateVelocity(sf::Time);
        void UpdatePosition(sf::Time);
        void Update(sf::Time);
        float getRotation() const;
        sf::Vector2f getPosition() const;
        sf::Vector2f getVelocity() const;
        sf::Vector2f getAcceleration() const;


private:
        std::string mId;
        sf::Vector2f mPosition;
        float mRotation;
        sf::Vector2f mVelocity;
        sf::Vector2f mAcceleration;
};

#endif // ENTITY_H

and here is the cpp file:

#include "../include/Entity.h"

Entity::Entity(std::string id, sf::Vector2f position, float rotation)
        : mId(id)
        , mPosition(position)
        , mRotation(rotation)
{
}

Entity::~Entity()
{
}


void Entity::UpdateVelocity(sf::Time dt)
{
        mVelocity += mAcceleration;
}

void Entity::UpdatePosition(sf::Time dt)
{
        mPosition += mVelocity;
}

void Entity::Update(sf::Time dt)
{
        UpdateVelocity(dt);
        UpdatePosition(dt);
}

float Entity::getRotation() const
{
        return mRotation;
}

sf::Vector2f Entity::getPosition() const
{
        return mPosition;
}

sf::Vector2f Entity::getVelocity() const
{
        return mVelocity;
}

sf::Vector2f Entity::getAcceleration() const
{
        return mAcceleration;
}

Any help is much appreciated!

Veritas
  • 2,150
  • 3
  • 16
  • 40

1 Answers1

6

You are missing the implementation of some virtual methods:

    virtual sf::FloatRect getBoundingRect() const;
    virtual float getRadius() const;

If you don't want your Entity class to implement these, declare them as pure virtual:

    virtual sf::FloatRect getBoundingRect() const = 0;
    virtual float getRadius() const = 0;

Note that, as commented by @JoachimIsaksson, it isn't completely obvious whether you need your destructor to be pure virtual. You have provided an empty implementation for it, but you still require derived types to implement it. It may be worth considering whether you need it to be pure virtual.

juanchopanza
  • 223,364
  • 34
  • 402
  • 480
  • Thank you very much they were supposed to be declared as pure virtuals and I completely missed it! – Veritas Apr 20 '14 at 11:30
  • @Veritas OK, I was adding that as an alternative. – juanchopanza Apr 20 '14 at 11:32
  • @Veritas `~Entity()` is also declared pure virtual and implemented anyway. – Joachim Isaksson Apr 20 '14 at 11:37
  • @juanchopanza Yes, but an empty virtual implementation isn't normally very useful so thought I'd point it out in case it wasn't intentional. – Joachim Isaksson Apr 20 '14 at 11:42
  • A pure virtual destructor **must** have its body defined - it still gets called after the derived destructors have run. The effect of making a function pure virtual is to force derived classes to override it. This is orthogonal to whether or not it has an implementation. – M.M Apr 20 '14 at 13:33
  • @MattMcNabb Yes, good point. The question should be whether OP needs it to be pure virtual or not, not whether they need the implementation. Corrected. – juanchopanza Apr 20 '14 at 13:42
  • Sometimes you want to keep a class abstract and you don't want any pure virtual functions. Declaring the destructor as pure virtual solves this so I tend to always add it on abstract classes for consistency. – Veritas Apr 20 '14 at 15:31