【问题标题】:C++ - Unable to instantiate abstract classC++ - 无法实例化抽象类
【发布时间】:2012-09-08 08:23:38
【问题描述】:

(我对 C++ 还很陌生,所以希望这只是一个菜鸟错误)

我的代码有问题,我有一个需要许多属性的类“播放器”,我试图通过使用抽象类来给它:

//player.h

class Player : public IUpdate, public IPositionable, public IMoveable, public IDrawable
{
public:
    Player(void);
    SDL_Rect get_position();
    void move(Uint32 dTime);
    void update(Uint32 dTime);
    void show(SDL_Surface* destination);
    ~Player(void);
private:
    SDL_Surface texture;
    int x, y;
};

我正在重写纯虚函数:

//Player.cpp
Player::Player(void)
{
}

SDL_Rect Player::get_position()
{
    SDL_Rect rect;
    rect.h = 0;
    return rect;
}

void Player::move(Uint32 dTime)
{

}

void Player::update(Uint32 dTime)
{
    move(dTime);
}

void Player::show(SDL_Surface* destination)
{
    apply_surface(x, y, &texture, destination, NULL);
}

Player::~Player(void)
{
}

但是我不断收到编译错误:C2259: 'Player' : cannot instantiate abstract class

据我所知,纯虚函数应该被覆盖,我的谷歌搜索告诉我,这会使 Player 非抽象,但 Player 似乎仍然是抽象的。

编辑: 纯虚函数:

class IPositionable
{
public:
    virtual SDL_Rect get_position() = 0;
private:
    int posX, posY;
};

class IUpdate
{
public:
    virtual void update (Uint32 dTime) = 0;
};

class IMoveable
{
public:
    int velX, velY;
    virtual void move(Uint32 dTime) = 0;
};

class IDrawable
{
public:
    virtual void show() = 0;
private:
    SDL_Surface texture;
};

class IHitbox
{
    virtual void check_collsion() = 0;
};

class IAnimated
{
    virtual void next_frame() = 0;
    int state, frame;
    int rows, columns;
};

【问题讨论】:

  • Player 必须覆盖其派生类的所有纯虚函数

标签: c++ visual-c++ abstract-class virtual-functions


【解决方案1】:

你的问题在这里:

class IDrawable
{
public:
    virtual void show() = 0;
};

void Player::show(SDL_Surface* destination)
{
    apply_surface(x, y, &texture, destination, NULL);
}

注意Player::show(SDL_Surface* destination)不会覆盖纯虚方法IDrawable::show()
为了覆盖该方法,您需要在派生类中使用完全相同的函数签名(只允许协变返回类型
您现在拥有的是派生类中名为show() 的方法,hides 基类中名为show() 的方法不会覆盖它。由于您没有为您的类的所有纯虚函数提供定义,Player 编译器正确地告诉您它是一个抽象类。

【讨论】:

    【解决方案2】:

    您可能没有覆盖其中一个基的纯虚函数,而是声明并定义了一个签名略有不同的函数,如下所示:

    struct base {
        virtual void foo(double d) = 0;
    };
    
    struct derived: base {
        // does not override base::foo; possible subtle error
        void foo(int i);
    }
    

    您可能希望通过查看代码来仔细检查您的代码。如果您使用的是 C++11,则可以将函数标记为 override 以捕获此类错误。

    【讨论】:

      【解决方案3】:

      抽象类是抽象的 - 即某些东西没有被定义,而只是被声明。

      您需要定义所有这些方法。由于我没有这些类的声明,因此我无法就您缺少哪些方法向您提供建议。

      【讨论】:

        【解决方案4】:

        在 C++ 中,除非专门编写,否则函数不是虚函数:

        virtual void move(Uint32 dTime);
        

        pure virtual function 的定义如下:

        virtual void move(Uint32 dTime) = 0;
        

        您继承的“接口”(注意这是multiple inheritance.. C++ 的接口与类没有区别)具有您未实现的纯虚函数,从而使您的类抽象。

        【讨论】:

        • 我完全忘了添加纯虚函数。它们现在已被编辑到原始帖子中。
        【解决方案5】:

        这肯定是由于缺少对纯虚函数的覆盖造成的——也许只是一个细微的签名差异。

        我希望编译器会告诉你哪个函数仍未被覆盖,例如 (vc9):

        C2259: 'Player' : cannot instantiate abstract class
        due to following members:
        'void IUpdate::update(void)' : is abstract
        virtualclass.cpp(3) : see declaration of 'IUpdate::update'
        

        如果您的编译器没有报告这一点,您可以通过删除继承的接口来检查。

        【讨论】:

        • 不幸的是它告诉我这样的事情:(
        • @user1673234 你正在使用哪个编译器和版本
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2015-08-04
        • 1970-01-01
        • 2017-02-05
        • 2015-10-06
        • 1970-01-01
        相关资源
        最近更新 更多