我试图让派生类(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}}值并将其输出?
答案 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;
}