派生类继承了吸气剂,找不到返回正确值的方法

时间:2019-07-30 19:53:41

标签: c++ inheritance getter

我试图让派生类(Hero)从基类(Entity)继承getter函数的代码。但是,我无法找到如何通过此getter访问Hero的私有变量(正确的值)。

我正计划为Hero类以及另一个派生类(Enemy)分配相似的吸气剂(总共约10个)。从技术上讲,我可以写出两个类的每个getter,但我宁愿限制代码重复。无论如何,我可以在Entity中编写代码并让两个派生类继承它吗?

#include <iostream>
using namespace std;

class Entity{
public:
    Entity() {
       this->speed = 0;
    }
    short getSpeed() {
       return this->speed;
    }

private:
    string name;
    short speed;
};

class Hero : public Entity{
public:
    Hero(short speed) {
       this->speed = speed;
    }

private:
    short speed;
};

int main()
{
    Hero hero1(2);
    cout << hero1.getSpeed() << endl;
    return 0;
}

输出给我0,这是实体的默认值。有什么方法可以访问hero1的{​​{1}}值并将其输出?

2 个答案:

答案 0 :(得分:4)

为什么要让base的方法返回专用于派生的值?那不是您通常要做的事情。

退后一步,思考一下您实际想要实现的目标。如果每个Enitity都有一个speed成员,并且如果每个Hero是一个Entity,则Hero不需要另外的私有speed

相反,Hero应该在构造函数中初始化其Entity部分:

class Entity{
public:
    Entity(short speed = 0) : speed(speed) {}   // <- fixed constructor
    short getSpeed() { return speed; }
    void setSpeed(short s) { speed = s; }
private:
    short speed;
};

class Hero : public Entity{
public:
    Hero(short speed) : Entity(speed) {}    
};

我更改了Entity的构造函数,以便可以为speed传递初始值。然后Hero的构造函数可以正确初始化其Entity子对象。

  

是否有任何方法可以访问hero1值2并将其输出?

如果您确实希望speed成为Hero的私有成员,那么也应该在Hero中实现getter,就像您为Entity所做的那样。但是,在两个类中都有一个speed,并且两个都有一个getter有点奇怪。选择speed是属于Entity还是属于Hero,两者都不太可能需要。

在编写代码之前,您应该回答的一个问题是:谁负责什么?

在上面的示例中,Entity负责管理其速度。我们可以这样说:Entity只需要一种获取速度的方法。实际是如何做到的是子类的商务性(想想木椅和穿着速度+5的靴子的精灵弓箭手)。在这样的代码中

struct Entity{
    virtual short getSpeed() { return 0; }
};

我无法比别人解释得更好,因此我引用了cppreference

  

虚拟函数是成员函数,其行为可以是   在派生类中重写。与非虚拟功能相反,   即使没有编译时,被覆盖的行为也会保留   有关类的实际类型的信息。如果派生类是   使用指针或对基类的引用(对   覆盖的虚函数将调用在   派生类。 [...]

TL; DR:virtual启用带有指针和引用的动态分配。鼓励子类使用其自己的实现重写该方法。

现在,子类可以使用默认实现(木制椅子),也可以提供自己的子类:

struct ElvenArcher : Entity {
    bool hasBootsOfSpeed = true;
    short baseSpeed = 10;
    short getSpeed() override {
        return hasBootsOfSpeed ? (baseSpeed+5) : baseSpeed;
    }
};

此处override声明该方法在基类中重写了一个。

PS:请注意,我将重要部分放在了粗体中。从您的问题尚不清楚,什么是编写代码的正确方法,并且此答案主要来自于注释太长的注释。我试图概述两个极端。您实际需要的可能介于两者之间。

答案 1 :(得分:1)

由于速度是一个私有变量,因此您需要在英雄类中实现getSpeed

这是您的更正代码:

#include <iostream>
using namespace std;

class Entity{
public:
    Entity() {
       this->speed = 0;
    }
    short getSpeed() {
       return this->speed;
    }

private:
    string name;
    short speed;
};

class Hero : public Entity{
public:
    Hero(short speed) {
       this->speed = speed;
    }

    short getSpeed() {
       return this->speed;
    }
private:
    short speed;
};

int main()
{
    Hero hero1(2);
    cout << hero1.getSpeed() << endl;
    return 0;
}

也许最好使用protected

#include <iostream>
using namespace std;

class Entity{
public:
    Entity() {
       this->speed = 0;
    }
    short getSpeed() {
       return this->speed;
    }

protected:
    string name;
    short speed;
};

class Hero : public Entity{
public:
    Hero(short speed) {
       this->speed = speed;
    }
};

int main()
{
    Hero hero1(2);
    cout << hero1.getSpeed() << endl;
    return 0;
}