访问子类参数

Accessing subclass arguments

我最近向我的角色 class 添加了一个子class 敌人,它在其构造函数中再接收两个参数。

Enemy::Enemy(const string &name, int health, int stamina, bool _isEnemy, bool _roaming) : Character(name, health, stamina), isEnemy(_isEnemy), roaming(_roaming){
    this->name = name;
    this->stamina = stamina;
    this->isEnemy = _isEnemy;
    this->roaming = _roaming;

我的角色 class 也有健康耐力和当前房间的吸气剂和吸气剂。在我的 main 中,我有一个 Enemy 类型的指针向量,我只使用一个简单的 for 循环来选择敌人并调用特定函数,如 getCurrentRoom()

for(int i = 0; i < enemies.size(); i++) {
            if(currentRoom == enemies[i]->getCurrentRoom()) {
                cout << enemies[i]->getName() << " HP: " << enemies[i]->getHealth() << " " << enemies[i]->getName()
                     << " ST: " << enemies[i]->getStamina() << endl;
            }

如果他们与玩家在同一个房间,这只会显示敌人的 HP 和 ST。但是当调试查看 enemy[0] 的值时,例如它有 Character object which I'm guessing is there due to it being the base class but also values from its own Enemy class with incorrect health and it is unable to access its current room

getCurrentRoom() 只是 returns 房间类型的指针。 subclass 无法访问的原因是因为它 returns 的指针在 Character.h 中处于私有状态吗?

如果 Character class 中声明的 getterssetters 是 public 而不是纯虚拟的,并且 Enemy class publicly继承自Character,像这样:

class Enemy : public Character

Enemy class 不需要(也不应该有)getterssetters 作为名称、健康和耐力变量。检查这些条件是否成立。

此外,查看 Enemy class 构造函数的实现,假设 Character 构造函数已经设置了名称、健康和体力,则无需再次设置Enemy 构造函数的主体(假设您没有在 Enemy class 中声明另外三个名为 name、health 和 stamina 的变量,如果这样做,这是一个设计缺陷)。

另一件事,您通过 Enemy 构造函数按值传递名称变量。为了防止不必要的复制,从而产生更高效的代码,通过常量引用传递它,或者 std::move 它进入 Character 构造函数,这取决于 Character 构造函数是否也通过 name 变量传递值与否。这对于 health 和 stamina 变量来说不是必需的,因为它们很容易复制构造和移动构造。

总而言之,如果您的 Character 构造函数声明如下:

Character::Character(string name, int health, int stamina);

将您的 Enemy 构造函数修改为:

Enemy::Enemy(string name, int health, int stamina, bool _isEnemy, bool _roaming) : Character(std::move(name), health, stamina), isEnemy(_isEnemy), roaming(_romaing){
}

这将要求您将 Character 构造函数中的名称参数移动到 Character class 的名称成员中,如果尚未完成的话。

编辑:

要使用继承,角色 class 和敌人 class 应该是这样的,关于上面的代码片段:

//Character class 

class Character{
    private:
        //private data members
        std::string name;
        int health;
        int stamina;

    public:
        //constructor
        Character(const std::string& _name, int _health, int _stamina);

        //getters
        int get_health() const;
        int get_stamina();
        std::string get_name() const;

        //setters
        void set_health(int _health);
        void set_stamina(int _stamina);
        void set_name(const std::string& _name);
};

//Enemy class

//public inheritance from Character
class Enemy: public Character{
    private:
        //private data members
        bool isEnemy;
        bool roaming;

    public:
        //public constructor
        Enemy(const std::string& name, int health, int stamina, 
            bool _isEnemy, bool _roaming);
};

//Character class implementation

//set private data members in constructor
Character::Character(const std::string& _name, int _health, int _stamina)
          : name(_name), health(_health), stamina(_stamina){
}

//simple getter definitions 
int Character::get_health() const {
    return health;
}

int Character::get_stamina() const {
    return stamina;
}

std::string Character::get_name() const {
    return name;
}

//simple setters definitions
void Character::set_health(int _health) {
    health = _health;
}

void Character::set_stamina(int _stamina) {
    stamina = _stamina;
}

void Character::set_name(const std::string& _name) {
    name = _name;
}

//Enemy class implementation

//call character constructor, and set other private data members
Enemy(const std::string& name, int health, int stamina, 
        bool _isEnemy, bool _roaming) : Character(name, health, stamina),
        isEnemy(_isEnemy), roaming(_roaming){
}

注意:您可能希望在 Enemy class 中为 roamingisEnemy 实施 getterssetters,在类似于字符 class 中的 getterssetters

注意名字、耐力和生命值是如何在 Enemy class 中重新声明的。这是因为它们已经存在于 Enemy 继承的角色 class 中。如果你想获取或设置名称、健康或耐力,请使用来自角色 class 的 public getter 和 setter。您可以像这样使用它们:

Enemy dragonEnemy("Dragon", 100, 50, true, true);

//using public getter
int dragonHealth = dragonEnemy.get_health();

//using public setter
dragonEnemy.set_stamina(55);