Consider the following:
#include <iostream>
class Base {
public:
void go(){this->doSomething();}
protected:
virtual void doSomething(){std::cout << "base";}
};
class DerivedA : public Base {
protected:
void doSomething() override {std::cout << "a";}
};
class DerivedB : public Base {
public:
Base * basePtr;
DerivedB()
:basePtr(new DerivedA())
{}
protected:
void doSomething() override {basePtr->doSomething();} // wont compile
};
int main(int , char *[])
{
DerivedB b;
b.go();
}
doSomething() in the DerivedB subclass will not compile, but I do not understand why this behavior exists! I am trying to access a virtual protected member function of my base class, which I would have thought would be allowed.
http://en.cppreference.com/w/cpp/language/access
In the section on protected member access, it says
"A protected member of a class Base can only be accessed 1) by the members and friends of Base 2) by the members and friends (until C++17) of any class derived from Base, but only when operating on an object of a type that is derived from Base (including this)"
According to point 2, if I cast down to the subclass (DerivedA), this would be allowed but I would then be in conflict with the condition that I am accessing a protected member function of a different class (which is not a base class, and would also not compile). Worse, if I knew the sub class type of the derived object, I could still not access it even if I cast to its common base.
Why is this behavior enforced? I assume it is probably going to be a side effect of allowing multiple inheritance etc but I can't think of exactly what it would be. It's annoying because now I have to make a public interface for something which is and should only be used by base or derived classes, which goes against the point of inheritance and access modifiers.