Search code examples
c++friend

Friend Function Accessibility Issue


I am trying to make a friend function for another class, but my current layout is causing access issues and header-include issues.

In my project I have two files: Class A and Class B. For the sake of brevity, everything is inlined in the header file, as it still demonstrates my issue.

#ifndef CLASSA
#define CLASSA

#include "ClassB.h"

class A {
   private:
      int x;
   public:
      A(int x) {
          this->x = x;
      }
      friend void testFriend(A in);
};

#endif

#pragma once
#ifndef CLASSB
#define CLASSB
#include <cstdio>
#include "ClassA.h"

class B {
public:
   void testFriend(A in) {
       printf("%d", in.x);
   }
};
#endif

However, with this setup, Visual Studio thinks that class A's private member elements are inaccessible despite it being a member function. Furthermore, they are including each other which will cause errors eventually. This setup works fine when these two classes are in the same header file, though. How can I achieve a setup like this, where one class has a member function that needs to be a friend with another class, and while having the two classes be in separate header files.


Solution

  • The declaration

    friend void testFriend(A in);
    

    makes a non-member function named testFriend a friend of the class. It does not make B::testFriend a friend of class A.

    You can solve the problem by making B a friend of A. This will require only a forward declaration.

    #ifndef CLASSA
    #define CLASSA
    
    // No need for this.
    // #include "ClassB.h"
    class B;
    
    class A {
       private:
          int x;
       public:
          A(int x) {
              this->x = x;
          }
    
          // This does not work.
          // friend void testFriend(A in);
    
          // Make B a friend of the class.
          friend B;
    };
    
    #endif
    

    Now,

    class B {
    public:
       void testFriend(A in) {
           printf("%d", in.x);
       }
    };
    

    should work just fine.