Search code examples
c++classoopc++11friend

How should I properly use a friend declaration in a nested class?


For example, suppose I made a code like :

class A
{
private:
    class B
    {
    private:
        int a;
        friend int A::foo(B &b);
    };
    int foo(B &b)
    {
        return b.a;
    }
};

Since a in B is private, to use a in function foo of A, I would use a friend so that foo can actually access a.

However this code gives error that it cannot access a. What is the problem of the code, and how should I change the code while keeping a private and A not being friend of B? Or is there a better way?


Solution

  • If you want to get only the a of B class you need a getter function. This should be the simplest way to go.

    class B
    {
    private:
        int a;
    public:
        // provide getter function
        const int& getMember_a()const { return a; }
    };
    

    and in the foo function

    const int& foo(const B &b)const 
    {
        return b.getMember_a(); // call the getter to get the a
    }
    

    Regarding the issue of your code; at the line friend int A::foo(B &b); in B class, it does not know that the function A::foo. Therefore we need to forward declare int foo(B &); before the class B. Then the question; whether A::foo(B &) knows about B. Also no. But fortunately, C++ allows having an incomplete type by forward declaring the classes as well. That means, following way-way, you can achieve the goal you want.

    class A
    {
    private:
        class B;      // forward declare class B for A::foo(B &)
        int foo(B &); // forward declare the member function of A
        class B
        {
        private:
            int a;
        public:
            friend int A::foo(B &b);
        };
    };
    // define, as a non-member friend function
    int A::foo(B &b)
    {
        return b.a;
    }