Search code examples
c++classinheritanceprotected

Inheritance of protected class


I have a doubt with this code ( it is a question into a test so I don't need to change ):

class X {
    protected:
    int v;
};

class Y : protected X {
public:
    Y() : v(0) {}
    
};

int main()
{
    Y *y = new Y();
    cout << y->v;
    delete y;
    return 0;
}

I was quite sure that it was good because the v member of X was accessible from Y because Y was the subclass of a protected Class which has a protected member ( v ) but I have a compilation error. Can someone help me to understand? thanks!


Solution

  • There are at least two problems.

    The first one is that the class definitions

    class X {
        protected:
        int v;
    };
    
    class Y : protected X {
    public:
        Y() : v(0) {}
        
    };
    

    are ijll-formed. From the C++17 Standard( 15.6.2 Initializing bases and members ):

    2 In a mem-initializer-id an initial unqualified identifier is looked up in the scope of the constructor’s class and, if not found in that scope, it is looked up in the scope containing the constructor’s definition. [ Note: If the constructor’s class contains a member with the same name as a direct or virtual base class of the class, a mem-initializer-id naming the member or base class and composed of a single identifier refers to the class member. A mem-initializer-id for the hidden base class may be specified using a qualified name. — end note ] Unless the mem-initializer-id names the constructor’s class, a non-static data member of the constructor’s class, or a direct or virtual base of that class, the mem-initializer is ill-formed.

    That is you may not use the non-static member v of the base class X as an initializing member in the ctor initialization of the class Y:

    Y() : v(0) {}
          ^^^^
    

    The second problem is that as the data member v is protected in the derived class Y then you may not directly access it outside the class as you are doing

    cout << y->v;
    

    Either make the data member public or create a public member function that will return the value of the data member v or a constant reference to the data member.