1

I have a class Animal, which has a subclass Dog, which has a subclass BigDog. The class Animal has a protected int legs. I am unable to access legs in the BigDog class functions or constructor.

class Animal {
protected:
    int legs = 0;
    Color eyeColor = Color(0,0,0);
public:
    virtual string getSound() const = 0;
};

class Dog : Animal {
public:
    string getSound() const override {
        string sound = "";
        int legI = legs;
        while (legI-- > 0) {
            sound+=" *step* ";
        }
        sound+="BARK";
        return sound;
    }
    Dog() : Animal() {
        legs = 4;
        eyeColor = Color(200,128,0);
    }
};

class BigDog : Dog {
public:
    //use the initializer of dog
    BigDog() : Dog() {
        legs = 4;
    }
    string getSound() const override {
        string sound = "";
        int legI = legs;
        while (legI-- > 0) {
            sound+=" *step* ";
        }
        sound+="BOOF BOOF";
        return sound;
    }
};

This code gives "error: ‘int Animal::legs’ is protected" when setting or reading legs from BigDog

Trevor Reid
  • 3,310
  • 4
  • 27
  • 46
DataDeer.net
  • 87
  • 1
  • 7
  • 1
    You have private inheritance. That's not what you want. – Ben Voigt Apr 03 '19 at 00:03
  • Possible duplicate of [Difference between private, public, and protected inheritance](https://stackoverflow.com/questions/860339/difference-between-private-public-and-protected-inheritance) – Tas Apr 03 '19 at 00:04

2 Answers2

4

When you write

class Dog : Animal { … };

what you're really writing is

class Dog : private Animal { … };

because the default access specifier for classes defined with class-key class is private [class.access.base]/2 (fancy way of saying: if you have a class that class will inherit everything to be private unless you explicitly say otherwise). Private inheritance means all protected and public members of the base class will be private in the derived class. Since Dog inherited all the Animal stuff privately, it's not accessible to BigDog anymore (which, by the way, also inherits all the Dog stuff privately). What you most likely wanted to write is

class Dog : public Animal { … };

and

class BigDog : public Dog { … };

Note: if you had a struct, the default would be public.

Michael Kenzel
  • 15,508
  • 2
  • 30
  • 39
2

You're using private inheritance, which implies that every inherited member becomes private. You want public inheritance.

class Dog : public Animal {
...
class BigDog : public Dog {

Note the keyword public here, which ensures that public members remain public and protected members remain protected. The access specifier for inheritance specifies the maximum visibility of any inherited member, so when it's private everything will be private. And, like with members of class classes, if you don't specify, the inheritance will assume that you mean private. More on that on cppreference.

Silvio Mayolo
  • 62,821
  • 6
  • 74
  • 116