Suslik
Suslik

Reputation: 1071

friend keyword for operator overloading

I tried to write an simple example for the <<-operator-overloading. Before, i've never used the keyword "friend". But it does not work without it. What is the mistake i did or why do i need the friend keyword here?

class rational{

public:
 rational(double num, double count)
    : n(num),c(count){}

 rational& operator+=(const rational& b){
    this->n+= b.n;
    this->c+= b.c;
    return *this;
 }

 friend std::ostream& operator<<(std::ostream& os, const rational& obj)
 {
 std::cout << obj.n << "," << obj.c << std::endl;
 return os;
 }

private:
 double n;
 double c;
};

Thanks

Upvotes: 6

Views: 2563

Answers (3)

Heisenberg
Heisenberg

Reputation: 5668

You want to stream objects whose internals are not accessible through their class' public interface, so the operator can't get at them. Then you have two choices: Either put a public member into the class which does the streaming

class T {
  public:
    void stream_to(std::ostream& os) const {os << obj.data_;}
  private:
    int data_;
};

and call that from the operator:

inline std::ostream& operator<<(std::ostream& os, const T& obj)
{
   obj.stream_to(os);
   return os;
}

or make the operator a friend

class T {
  public:
    friend std::ostream& operator<<(std::ostream&, const T&);
  private:
    int data_;
};

so that it can access the class' private parts:

inline std::ostream& operator<<(std::ostream& os, const T& obj)
{
   os << obj.data_;
   return os;
}

Upvotes: 2

Tristan Brindle
Tristan Brindle

Reputation: 16824

You didn't make any mistake. The friend keyword gives your operator<<() implementation access to private (and protected, if you had any) members of your class.

Note that because it's a friend, operator<<() here is implicitly a free function and not a member function (if it were a member function, it could access private things already!). Because it's declared and defined only inside the class, it can only be found by argument-dependent lookup, but this is fine for operator<< and is a detail you don't have to worry about yet.

Upvotes: 3

Fabio Ceconello
Fabio Ceconello

Reputation: 16049

You are declaring and defining the operator inside the class, thus without friend it has an implicit first operand of type rational. You wouldn't have such problem if you had declared the operator outside the class, but then you wouldn't have access to n and c.

Upvotes: 3

Related Questions