Why can’t a derived class call protected member function in this code?

Even though access control in C++ works on per-class basis (as opposed to per-instance basis), protected access specifier has some peculiarities.

The language specification wants to ensure that you are accessing a protected member of some base subobject that belongs to the derived class. You are not supposed to be able access protected members of some unrelated independent objects of base type. In particular, you cannot access protected members of freestanding objects of base type. You are only allowed to access protected members of base objects that are embedded into derived objects as base subobjects.

For this reason, you have to access protected members through pointer->member syntax, reference.member or object.member syntax, where the pointer/reference/object refers to the derived class.

This means that in your example, protected member somethingProtected() is not accessible through Base objects, Base * pointers or Base & references, but it is accessible through Derived objects, Derived * pointers and Derived & references. Your plain somethingProtected() access is allowed, since it is just a shorthand for this->somethingProtected() where this is of type Derived *.

b.somethingProtected() violates the above requirements.

Note that in accordance with the above rules in

void Derived::somethingDerived()
{
    Base *b = this;
    b->somethingProtected();    // ERROR
    this->somethingProtected(); // OK
}

the first call will also fail while the second one will compile, even though both are trying to access the same entity.

Leave a Comment