抽象类C ++

时间:2013-11-15 23:56:29

标签: c++ sdl virtual abstract

所以我的理解是,要在c ++中创建一个类抽象,你必须在该类中创建一个纯粹的虚拟方法。在我的代码中,我创建了一个抽象的GameObject类,它由我的Player类继承,但问题是我在我的Player.cpp中得到错误说错误LNK2001:未解析的extrenal符号“public:virtual void__thiscall GameObject :: Load(void)” (?加载@ GameObject @@ UAEXXZ)除了初始化之外的每个方法,当我将它们设置为全部= 0时,这会得到修复,我只是想知道为什么

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

4 个答案:

答案 0 :(得分:5)

可能通过非纯虚拟基类指针调用的每个虚方法都需要有一个实现。

您似乎对抽象/虚拟的工作原理有一个倒退的想法。你不选择抽象课,为什么?您选择将成员函数设置为纯虚拟,因为它没有合理的实现。然后,由于具有纯虚函数,该类变为抽象。

变成抽象的类并不意味着它的每一个函数都突然变成纯虚的。

您的错误是链接器错误。链接器正在寻找您未提供的GameObject::Load函数的实现。如果将该函数标记为纯虚函数,则链接器将不会查找实现。

答案 1 :(得分:0)

某些编译器要求对于每个签名,virtual关键字只在基类中指定一次。试试这个:

class GameObject
{
public:
    virtual void Initialise() = 0;
    virtual void Load() = 0;
    virtual void HandleEvents() = 0;
    virtual void Update() = 0;
    virtual void Draw() = 0;
...
};

class Player : public GameObject
{
public:
    void Initialise();
    void Load();
    void HandleEvents();
    void Update();
    void Draw();
...
};

答案 2 :(得分:0)

如果你不需要公共GameObject :: Initialise方法是纯虚拟的,至少给它一个空体,就像这样

class GameObject
{
public:
    void Initialise() {}
    ...
};

答案 3 :(得分:0)

另一个猜想:您是否有任何机会在代码中实现GameObject的任何实例化?你有这样的东西:

GameObject go;

或类似的东西:

void foo( GameObject go );

或类似的东西:

GameObject bar();

或类似的东西:

vector<GameObject> all_my_objects;