我为warrior
类定义了私有属性hp
和atk
,并假设它们不会由派生类继承。
然而,在下面的代码中,派生类knight
继承了一个公共方法attack
调用私有属性CCD_ 6。在这种情况下,knight.attack((仍然正常工作,并且似乎可以访问私有属性atk
,尽管它不应该由派生类继承。
我对此感到困惑。你能帮我解释一下幕后的机制吗?创建knight
类的实例时,它是否具有atk
属性
#include <cstdio>
class warrior{
private:
int hp,atk;
public:
void attack(int &enemyHP) {
enemyHP -= this->atk;
printf("Deal %d damage to the enemy.n", this->atk);
this->atk += 10;
}
warrior(int hp=100, int atk=20) {
this->hp = hp; this->atk = atk;
}
};
class knight:public warrior{
public:
knight(int hp=200, int atk=50) {}
};
int main()
{
int enemyHP=100;
knight Tom = knight();
Tom.attack(enemyHP); // Deal 20 damage to the enemy.
Tom.attack(enemyHP); // Deal 30 damage to the enemy.
}
当我创建knight类的实例时,它是否具有atk属性?
是的。但只有从warrior
继承的方法才能访问它。private
的目标是将可见性限制在定义它的类上,但它仍然存在于子类中,它们就是无法访问它(而不是诉诸于未定义的行为,比如访问实例的原始字节(。但由于knight
是warrior
,当它使用warrior
行为(在warrior
本身上定义的方法(时,他们可以很好地看到atk
。
这很好;atk
不是knight
的公共接口的一部分,但attack
是,为了使attack
工作,它需要查看warrior
的atk
。通过对直接访问隐藏warrior
的atk
,您已经做了足够的工作来确保knight
可以声明其自己的atk
成员(这将100%独立于warrior
的atk
,如果也声明了private
,则只能从knight
上定义的方法访问(。无论如何,它做它应该做的事:
- 公共方法在继承时继续工作,即使它们在私有成员上操作
- 私有属性不能被任何未定义为其自己类一部分的东西访问(除非通过
friend
进行访问(