Bubble
Bubble

Reputation: 23

What will happen when a class inherits a public method with reference to private properties?

I defined private properties hp and atk for warrior class and supposed that they won't be inherited by derived classes.

In the following code, however, The derived class knight inherits a public method attack which calls the private property atk. In this case, knight.attack() still functions properly and seems to have access to the private property atk though it wasn't supposed to be inherited by a derived class.

I am confused about this. Could you please help me to explain the mechanism behind the scene? When I create an instance of knight class, does it have the atk property?

#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.
}

Upvotes: 1

Views: 729

Answers (1)

ShadowRanger
ShadowRanger

Reputation: 155507

When I create an instance of knight class, does it have the atk property?

Yes, it does. But only methods inherited from warrior can access it. The goal of private is to limit visibility to the class that defines it, but it still exists in the child classes as well, they just can't access it (not without resorting to undefined behavior nonsense like accessing the raw bytes of the instance anyway). But since a knight is a warrior, when it uses warrior behaviors (methods defined on warrior itself), they can see atk just fine.

This is fine; atk isn't part of knight's public interface, but attack is, and for attack to work, it needs to see warrior's atk. By hiding warrior's atk from direct access, you've done enough to ensure knight could declare it's own atk member (which would be 100% independent of warrior's atk, and if also declared private would only be accessible from methods defined on knight). Regardless, it does what it should do:

  1. Public methods continue to work when inherited, even if they operate on private members
  2. Private attributes can't be accessed by anything not defined as part of their own class (unless made accessible via friend)

Upvotes: 1

Related Questions