Lets say I have a listener interface defined as:
class Listener
{
public:
virtual void doSomething(void) = 0;
}
and an abstract class that inherits publicly from my interface:
class AbstractBase: public Listener
{
public:
virtual void doSomething(void){ ...do something }
}
My derived class inherits from my AbstractBase using protected inheritance:
class Derived: protected AbstractBase
{
public:
Derived(Caller &c){ c.register(this); }
}
My Caller class notifies listeners that register for events:
class Caller
{
public:
void register(Listener *listenerPtr){...add listenerPtr to some container }
void raiseEvent(){...loop over registered listeners and call listenerPtr->doSomething();}
}
I then use the classes in the following manner:
int main(void)
{
Caller caller;
Derived derived(caller); // derived registers with caller in its constructor
caller.raiseEvent();
}
In the above code, I see that raiseEvent() is allowed to invoke listener.doSomething(). However, because I registered an instance of Derived as the listener, shouldn’t doSomething() be protected (and hence uncallable from Caller), since it inherits it’s implementation from AbstractBase via protected inheritance?
Access control is based on the static type, not the dynamic type. Therefore, since your
Calleruses a pointer toListener, it can use the interface defined by theListenerclass. If it receives a pointer to aDerived, it’s still basically treating it as aListener, so from its viewpoint,doSomething()is public, regardless of what a derived class might do.As an aside, I’d have some second thoughts about using
protectedinheritance. I’ve yet to see or hear of a good explanation of what it really means or a reasonable explanation of when or why you’d want to use it. In the D&E, Bjarne says (§13.9):