-2

I have a question about protected variables. Maybe i didn't really understand them but isnt the reason to use them, that child classes can use them? Overall i want to decrease the lifepoints.

Here is my code: Header file

class Fighter {
protected:
    int offensePoints;
    int defensePoints;
    int lifepoints;
    std::string name;
public:
    Fighter(const std::string n);
    virtual ~Fighter();
    virtual void attackFighter(Fighter * f);
    int randomval(int min, int max);
    bool isalive();
    void isattacked(Fighter * at, int dmg);
};

class Warrior : public Fighter
{
public:
    Warrior(const std::string n);
    virtual ~Warrior();
    void attackFighter(Fighter * f);
    int randomval(int min, int max);
    bool isalive();
    void isattacked(Fighter * at, int dmg);
};

Class Fighter:

void Fighter::attackFighter(Fighter * f)
{
    if (isalive())
    {
        f->lifepoints -= randomval(0, offensePoints);
    }
}

Class Warrior

void Warrior::attackFighter(Fighter * f)
{
    if (isalive())
    {
        f->lifepoints -= randomval(0, offensePoints);
    }
}
David Walser
  • 183
  • 20

2 Answers2

-1

Similar question as in Protected data in parent class not available in child class?

The solution is to make:

void Fighter::Attacked(int offensePoints) {
  if (isalive())
  {
      lifepoints -= randomval(0, offensePoints);
  }
}

a public function in Fighter, and call that (also removing code duplication).

Community
  • 1
  • 1
Hans Olsson
  • 11,123
  • 15
  • 38
-1

You can only access protected members in instances of your type (or derived from your type). You cannot access protected members of an instance of a parent or cousin type. In your case, the Derived class can only access the b member of a Derived instance, not of a different Base instance. Changing the constructor to take a Derived instance will also solve the problem.

Found there Accessing protected members in a derived class.

Which means in your case that you can't access to a fighter's lifepoint, but only to a warrior's.

Well this could work but I guess it's not what you are trying to do :

void Warrior::attackFighter(Warrior* w)'

Another solution is to call fighter's function attackFighter inside warrior's attack

void Warrior::attackFighter(Fighter * f)
{
   Fighter::attackFighter(f);
}

You could manage to change the behavior of Fighter::attackFighteranyway, for example:

void Warrior::attackFighter(Fighter * f)
{
   Fighter::attackFighter(f);
   Fighter::attackFighter(f); // This way, a warrior would attack twice when a simple fighter would only attack once.
}

This isn't very subtile but I am sure you understood the different possibilities you have to avoid your problem.

Community
  • 1
  • 1
Badda
  • 1,329
  • 2
  • 15
  • 40