Search code examples
c++polymorphismfriendpure-virtual

Pure Virtual Friend Class


I have class A that has a pointer to an instance of the pure virtual class B. Class C is derived from B and will automatically have a pointer to A (which is its parent), and needs to access its members. This can be achieved by adding friend class C inside class A, though then this is needed for every class that will derive from B.

Code example:

class A
{
public:
    friend class B; // This does not allow derived classes to be friends
    friend class C; // Now derived class B has access to `DoDomething`, but then this is needed for every single derived class

private:
    void DoDomething();
};


class B
{
    virtual void Tick() = 0;

protected:
    A* m_pointerToA; // <- is being set upon creating automatically
};


class C : public class B
{
    virtual void Tick()
    {
        m_pointerToA->DoSomething();
    }
};

Is there a way to make all derived classes from B have access to private and protected members of class A that they are pointing to, without having to add friend class X for each of them?


Solution

  • Since friendship is not inherited, you need to wrap all the functionality that relies on friendship into protected functions of the base class B. This will let all classes deriving from B access the functionality of A that needs "befriending":

    class B {
        virtual void Tick() = 0;
    protected:
        A* m_pointerToA; // <- is being set upon creating automatically
        void callDoSomething() {
            m_pointerToA->DoSomething();
        }
    };
    
    
    class C : public class B {
        virtual void Tick() {
            std::cout << "Class C is about to tick..." << std::endl;
            callDoSomething();
        }
    };
    
    class D : public class B {
        virtual void Tick() {
            callDoSomething();
            std::cout << "Class D has just ticked!" << std::endl;
        }
    };
    

    This effectively localizes the area where the friendship is used in your class hierarchy to class B, which helps with encapsulation.