Search code examples
c++functionfriend

How to use friend function in multiple classes


I am trying to create a non-member operator<<. However, I want the operator to be accessible to two of my classes. The operator is

void operator<< (ClassA & a, ClassB & b)

In the two classes public part, I say:

friend void operator<< (ClassA & a, ClassB & b);

However, it turned out that the operator can access the private member variable in CLass B but cannot access private member variable in Class A.

Why?

The real code: In the cpp file:

void operator<< (Hand& h, Deck& d){

    h.hand.push_back(d.card[0]);
    sort(h.hand.begin(),h.hand.end());
    d.card.erase(d.card.begin());
}

In the header file:

class Deck {

private:
    vector<Card> card;

public:
    friend void operator<< (Hand& , Deck& );
};

class Hand {

private:
    vector<Card> hand;

public:
    friend void operator<< (Hand& , Deck& );
};

And the card file didn't work.


Solution

  • Update to the edited question: the following code compiles no problem for me:

    #include <vector>
    #include <algorithm>
    typedef int Card;
    
    class Hand; // NOTE forward declaration
    
    class Deck {
    private:
        std::vector<Card> card;
    
    public:
        friend void operator<< (Hand& , Deck&);
    };
    
    class Hand {
    private:
        std::vector<Card> hand;
    
    public:
        friend void operator<< (Hand& , Deck&);
    };
    
    void operator<< (Hand& h, Deck& d) {
        h.hand.push_back(d.card[0]);
        std::sort(h.hand.begin(),h.hand.end());
        d.card.erase(d.card.begin());
    }
    
    int main()
    {
    }
    

    Did you forget to forward declare Hand in the header file?


    You might be confused because you can define the body of the static friend function inside one of the class's declarations.

    Still, a friend declaration is always just a declaration. So, in fact

    struct A;
    struct B;
    
    struct A
    {
        friend bool operator<<(A const&, B const&);
    };
    
    struct B
    {
        friend bool operator<<(A const&, B const&);
    };
    
    bool operator<<(A const&, B const&)
    {
        // access to both A and B
        return false;
    }
    

    Is equivalent, to

    struct A;
    struct B;
    
    struct A
    {
        friend bool operator<<(A const&, B const&)
        {
            // access to both A and B
            return false;
        }
    };
    
    struct B
    {
        friend bool operator<<(A const&, B const&);
    };