Search code examples
c++protectedderived-class

How to access protected base class function, from derived class through base class ptr


I have abstract class A, from which I inherit a number of classes. In the derived classes I am trying to access protected function in A trough A pointer. But I get a compiler error.

class A
{
   protected:
        virtual  void f()=0;
};

class D : public A
{
    public:
         D(A* aa) :mAPtr(aa){}
         void g();

    protected:
         virtual void f();

    private:
      A* mAPtr; // ptr shows to some derived class instance
};

void D::f(){  }


void D::g()
{
   mAPtr->f();
}

The compiler error says : cannot access protected member A::f declared in class A.

If I declare mAPtr to be D*, instead A* everything compiles. And I don't understand why is this.


Solution

  • Relying on private access works on unrelated instances of the same type.

    Relying on protected access works on unrelated instances of the same type (and of more derived types).

    However, relying on protected access does not work on unrelated instances of a base type.

    [n3290: 11.5/1]: When a friend or a member function of a derived class references a protected nonstatic member function or protected nonstatic data member of a base class, an access check applies in addition to those described earlier in clause 11. Except when forming a pointer to member (5.3.1), the access must be through a pointer to, reference to, or object of the derived class itself (or any class derived from that class) (5.2.5). If the access is to form a pointer to member, the nested-name-specifier shall name the derived class (or any class derived from that class).

    So D or something derived from D, but not A.

    It's an oft-questioned cute oddity about C++ that nonetheless is designed to try to avoid pitfalls. After all, you don't know what type *mAPtr really has.