Let’s say I have the following class hierarchy:
class Base
{
protected:
virtual void foo() = 0;
friend class Other;
};
class Derived : public Base
{
protected:
void foo() { /* Some implementation */ };
};
class Other
{
public:
void bar()
{
Derived* a = new Derived();
a->foo(); // Compiler error: foo() is protected within this context
};
};
I guess I could change it too a->Base::foo() but since foo() is pure virtual in the Base class, the call will result in calling Derived::foo() anyway.
However, the compiler seems to refuse a->foo(). I guess it is logical, but I can’t really understand why. Am I missing something ? Can’t (shouldn’t) it handle this special case ?
Thank you.
When you qualify a method name with a class name, as in
Base::foo()dynamic dispatch (run-time binding) does not apply. It will always call theBaseimplementation offoo(), no matter iffoo()is virtual or not. Since in this case it is pure virtual, there is no implementation and the compiler complains.Your second problem is that in C++, friendship is not inherited. If you want
Otherto have special access toDerived, it needs to be a friend ofDerivedspecifically.This, on the other hand, works:
Because here, you are calling
foo()on aBase*wherefoo()is public, and since you are not qualifyingfoo()with a class name, it uses dynamic dispatch and ends up calling theDerivedversion ofFoo.