Reputation: 1071
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
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
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
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