10

Friend functions should be able to access a class private members right? So what have I done wrong here? I've included my .h file with the operator<< I intent to befriend with the class.

#include <iostream>

using namespace std;
class fun
{
private:
    int a;
    int b;
    int c;


public:
    fun(int a, int b);
    void my_swap();
    int a_func();
    void print();

    friend ostream& operator<<(ostream& out, const fun& fun);
};

ostream& operator<<(ostream& out, fun& fun)
{
    out << "a= " << fun.a << ", b= " << fun.b << std::endl;

    return out;
}
starcorn
  • 8,261
  • 23
  • 83
  • 124

3 Answers3

13

In here...

ostream& operator<<(ostream& out, fun& fun)
{
    out << "a= " << fun.a << ", b= " << fun.b << std::endl;

    return out;
}

you need

ostream& operator<<(ostream& out, const fun& fun)
{
    out << "a= " << fun.a << ", b= " << fun.b << std::endl;

    return out;
}

(I've been bitten on the bum by this numerous times; the definition of your operator overload doesn't quite match the declaration, so it is thought to be a different function.)

Brian Hooper
  • 21,544
  • 24
  • 88
  • 139
  • Does `fun&` always have to be `const`? – Peter Chaula Jan 02 '17 at 07:38
  • 1
    @peter No it does not have to be const ( although your declaration must match your definition). However it's a 'best practice' to do so. As a user of the function, you do not expect that writing to an output stream changes the state of your object. – Bruno Hendrickx Feb 21 '19 at 09:23
6

The signatures don't match. Your non-member function takes fun& fun, the friend declared on takes const fun& fun.

Puppy
  • 144,682
  • 38
  • 256
  • 465
0

You can avoid these kinds of errors by writing the friend function definition inside the class definition:

class fun
{
    //...

    friend ostream& operator<<(ostream& out, const fun& f)
    {
        out << "a= " << f.a << ", b= " << f.b << std::endl;
        return out;
    }
};

The downside is that every call to operator<< is inlined, which might lead to code bloat.

(Also note that the parameter cannot be called fun because that name already denotes a type.)

fredoverflow
  • 256,549
  • 94
  • 388
  • 662