错误消息:不允许抽象类类型 "X" 的对象:纯虚拟"Y"没有覆盖器

Error message: Object of abstract class type "X" is not allowed: Pure virtual "Y" has no overrider

本文关键字:虚拟 覆盖 不允许 消息 抽象类 类型 错误 对象      更新时间:2023-10-16

敌人.h

class Enemy
{
    int hp;
public:
    Enemy(int);
    void setHP(int);
    int getHP();
    virtual int attack() = 0;
};

敌人.cpp

Enemy::Enemy(int playerXP)
{
    if (playerXP == 0) {
        hp = rand() % 5 + 1;
    }
    else if (playerXP > 0) {
        hp = rand() % (playerXP * 5) + 1;
    }
}
void Enemy::setHP(int currentHP)
{
    hp = currentHP;
}
int Enemy::getHP()
{
    return hp;
}

收割者

#pragma once
#include "Enemy.h"
class Reaper : public Enemy
{
public:
    Reaper(int playerXP) : Enemy(playerXP)
    {   
    }
    int attack(int, int);
};

reaper.cpp

int Reaper::attack(int pa, int php)
{
    int eatk = 0;
    if (pa == 0) {
        eatk = php * .5;
    }
    else {
        eatk = rand() % php * .25;
    }
    return eatk;
}

错误:

不允许抽象类类型的"收割者"的对象: 纯虚拟功能"敌人:攻击"没有效力。

我的问题是..为什么我会遇到此错误?我试图理解为什么要得到这个,以及解决该问题的任何可能答案。

Reaper是抽象的,因为它不是覆盖抽象Enemy::attack()方法,它是 Overloading 它。因此,您不能直接创建Reaper的任何对象实例。

当派生的类想要覆盖基类的虚拟方法时,派生的方法必须具有与它所覆盖的基本方法相同的签名。这意味着它具有相同的返回类型(或至少是兼容的协变返回类型(,调用约定,参数列表和constness。

Reaper::attack()的参数列表与Enemy::attack()不同。这就是为什么 Reaper::attack()过载而不是 Override

在C 11及以后,您可以(并且应该(使用新的override关键字标记Reaper::attack(),例如:

class Reaper : public Enemy
{
public:
    ...    
    int attack(int, int) override;
};

这样,编译器将采取额外的步骤来验证是否存在兼容的基本方法,如果没有找到,则将发出更有意义的错误消息。例如,使用override时,该现场演示会产生这些错误,如上所述:

prog.cpp:41:9:错误:" int caper ::攻击(int,int("标记为"覆盖",但不会覆盖     INT攻击(INT,INT(超越;         ^~~~~~prog.cpp:在函数" int main(("中:prog.cpp:57:9:错误:无法将变量" r"声明为抽象类型的"收割机"  收割机r(0(;         ^prog.cpp:34:7:注意:因为以下虚拟函数在"收割机"中是纯粹的: 阶级收割者:公共敌人       ^~~~~~prog.cpp:11:17:注意:虚拟INT敌人:: Attack((     虚拟int攻击((= 0;                 ^~~~~~

编译器没有意识到您要覆盖基类中的攻击功能。它将int attack()int attack(int, int)视为两个不同的功能,因为它们具有不同的类型签名。结果是您的Reaper类具有两个函数,其中一个是纯虚拟函数。使用override关键字可以帮助避免这些错误,尽管仅在C 11和更新中可用。