Search code examples
c++sdlvirtualabstract

abstract classes C++


So it is my understanding that to make a class abstract in c++ you have to create one, just one, pure virtual method in that class. In my code i create an abstract GameObject class, which is inherited by my Player class, but the problem is i get errors in my Player.cpp saying error LNK2001: unresolved extrenal symbol "public:virtual void__thiscall GameObject::Load(void)" (?Load@GameObject@@UAEXXZ) for every method except the initialise, and this gets fixed when i set them all = 0, im just wondering why

// Abstract class to provide derived classes with common attributes

#include <SDL.h>
#include "AnimationManager.h"
#include "Debug.h"
#include "InputHandler.h"

class GameObject
{
public:
    virtual void Initialise() = 0;
    virtual void Load();
    virtual void HandleEvents();
    virtual void Update();
    virtual void Draw();
    Vector2D* position;
    int currantFrame;
    SDL_Renderer* renderer;
    float speed;
    bool alive;
};



#include "GameObject.h"

class Player : public GameObject
{
public:
    virtual void Initialise();
    virtual void Load();
    virtual void HandleEvents();
    virtual void Update();
    virtual void Draw();
    Player(SDL_Renderer* r);
    ~Player();
};



#include "Player.h"

Player::Player(SDL_Renderer* r)
{
    renderer = r;
}

Player::~Player()
{
}

void Player::Initialise()
{
    position = new Vector2D(10, 10);
    currantFrame = 0;
}

void Player::Load()
{
    TheAnimationManager::Instance()->load("Assets/circle.png", "player", renderer);
}

void Player::HandleEvents()
{
    SDL_Event event;

    if (SDL_PollEvent(&event))
    {
        switch(event.type)
        {
            case SDL_KEYDOWN:

                switch(event.key.keysym.sym)
                {
                    case SDLK_a:
                        DEBUG_MSG("A Pressed");
                        position->m_x -= 10;
                    break;

                    case SDLK_d:
                        DEBUG_MSG("D Pressed");
                        position->m_x += 10;
                    break;
                }

            break;
        }
    }
}

void Player::Update()
{
    Vector2D* p = TheInputHandler::Instance()->GetMousePosition();
    DEBUG_MSG(p->GetY());
    DEBUG_MSG(p->GetX());

    currantFrame = int(((SDL_GetTicks() / 100) % 4));
}

void Player::Draw()
{
    TheAnimationManager::Instance()->Animate("player", (int)position->GetX(), (int)position->GetY(), 90, 82, 0, currantFrame, renderer, SDL_FLIP_NONE);
}

Solution

  • Every virtual method which might be called through a base class pointer that isn't pure virtual needs to have an implementation.

    You seem to have a backwards idea of how abstract/virtual works. You don't choose to make a class abstract, why would you? You choose to make a member function pure virtual, because there is no sensible implementation for it. Then, as a consequence of having a pure virtual function, the class becomes abstract.

    The class becoming abstract does not mean that every one of its functions suddenly becomes pure virtual.

    Your error is a linker error. The linker was looking for the implementation of the GameObject::Load function, which you didn't provide. If you mark the function as pure virtual, the linker won't look for an implementation.