Robert
Robert

Reputation: 71

Why can't I access inherited protected fields in a derived constructor's member initialization list?

I'm new to OOP. I recently learned some things about Inheritence in C++, and that a protected field can't be accessed from outside of the class, but it can be accessed in inherited classes. I have some problems with my code and I don't understand what is wrong:

class Base
{
protected:
    int x;
    int y;
    int z;
public:
    Base(int a, int b): x(a), y(b) { cout << "Base constructor" << endl; };
    Base(const Base& prev) : x(prev.x), y(prev.y) { cout << "Base copy constructor" << endl; };

    void print_x()
    {
        cout << x << endl;
    }

    void print_y()
    {
        cout << y << endl;
    }

    ~Base() { cout << "Base destructor" << endl; };
};

class Derived : public Base
{
public:
    Derived(int a, int b): x(a), y(b) { cout << "Derived constructor" << endl; };    ////////ERROR : Class 
 'Derived' does not have any fields named 'x' and 'y'
};

int main()
{
    Base* b = new Base(10, 20);
    Derived* d = new Derived(10, 20);
    delete b;
    delete d;
    return 0;
}

If Derived inherits Base, why does the compiler say that Derived doesn't have the fields x and y?

Upvotes: 2

Views: 457

Answers (1)

463035818_is_not_an_ai
463035818_is_not_an_ai

Reputation: 123431

You can access them in Derived, but they are members of Base and cannot be initialized directly in the member initialization list of Derived. This also wouldn't work if they were public. Note that the Base class is initialized before the members of Derived are initialized.

To initialize the base, you can call its constructor in the Derived's member initialization list:

class Derived : public Base
{
  public:
      Derived(int a, int b) : Base(a, b)  {  }; 
};

For more details, see here: https://en.cppreference.com/w/cpp/language/constructor

PS: Note that with respect to the member initialization list, there is also no difference to members that are private in the base. All members of the base are inherited, and initialized before members of the derived are initialized.

You miss to initialize z, and in your example there is no reason to use new and delete. If you fix the above, you get same output with this code:

int main()
{
    Base b(10,20);
    Derived d(10,20);
}

Last, but not least, if you plan to use Derived polymorphically, you need to declare the destructor of Base as virtual.

Upvotes: 10

Related Questions