2

I've been trying to find a way to have two classes, where each class has a member function, and each member function is a friend of the other class.

To illustrate:

#include <iostream>

class A;

class B
{
    friend void A::func_A(); // compiler error: invalid use of incomplete type 'class A'
public:
    void func_B() { std::cout << "Function B\n"; }
};

class A
{
    friend void B::func_B();
public:
    void func_A() { std::cout << "Function A\n"; }
};

int main()
{
    A a;
    B b;
    
    a.func_A();
    b.func_B();
}

I understand why this is happening; A has only been declared and not defined, therefore B cannot friend its member function func_A() as it doesn't know what it is. For B to know its definition, class A's definition would have to be above class B's. The problem then is the same except it's class A now which is unable to access B's member function.

My question is if there is a way around this cyclic dependency. I know C++ allows the friending of an entire class, which would resolve this issue. However, as far as I'm aware, it's best practice to restrict the visibility of members as much as possible.

Bwyan Eh
  • 23
  • 3
  • You might want to think about why do you need such structure. Is it so you can access private members of the other class? That's why you have public getters. – Ranoiaetep Jun 12 '21 at 23:07
  • This was just me trying to get my head around the friends concept, though I agree getters would suffice in most cases. There might be a situation where a class has many members, and thus it's more convenient to friend a function that uses a lot of them rather than to have multiple getters that may otherwise only be used by that one function. – Bwyan Eh Jun 12 '21 at 23:26

1 Answers1

2

You can do something like this, though it's probably not worth the trouble.

class B {
  friend class AccessorForAFuncA;
};

class A {
  void func_A();
};

class AccessorForAFuncA {
private:
  static void DoThingsWithPrivatePartsOf(B*);
  friend void A::func_A();
};

AccessorForAFuncA is a helper class that accesses private parts of B on behalf of A::funcA. Only A::funcA is granted this indirect access.

Igor Tandetnik
  • 50,461
  • 4
  • 56
  • 85