Reputation: 43598
compilation error when I overload cout operator inside the class
What I am missing?
Here after the source code. The problem disappear when I define the overload operator outside the class
#include <iostream>
using namespace std;
class Box {
public:
int l, b, h;
Box(int length, int breadth, int height) : l(length), b(breadth), h(height) {}
#if 1
ostream& operator<<(ostream& os) {
os << (l * b * h);
return os;
}
#endif
};
#if 0
ostream& operator<<(ostream& os, Box inb) {
os << (inb.l * inb.b * inb.h);
return os;
}
#endif
int main(void) {
Box B(3,4,5);
cout << B << endl;
return 0;
}
Upvotes: 0
Views: 73
Reputation: 181027
You can't overload operator <<
that way and have it work like normal. When you have
ostream& operator<<(ostream& os) {
os << (l * b * h);
return os;
}
What you really have is
ostream& operator<<(Box& this_, ostream& os) {
os << (this_.l * this_.b * this_.h);
return os;
}
Which means you would need to call cout
like
B << cout << endl;
The reason for this is that all class member functions have an implicit parameter of a reference type to the class as their first parameter. The compiler inserts this for you as that is how the member function knows which object to work on.
Upvotes: 1
Reputation: 72473
The expression X << Y
(when at least one operand has class or enum type) looks for whether operator<<(X, Y)
or X.operator(Y)
can be called.
So in cout << B
, it looks for operator<<(cout, B)
and cout.operator<<(B)
. Notice it's not at all looking for members of B
. It looks for members of cout
, but you can't add new members to a standard library class. So you need to define the non-member function.
The member you did define would make B << std::cout << std::endl;
work, but that doesn't look right, obviously.
One other option, necessary if the operator needs to use private members of the class, or nice if we just want the operator visible in the class's public
section, is to declare it a friend
, which is really a non-member:
class Box {
public:
Box(int length, int breadth, int height) : l(length), b(breadth), h(height) {}
friend std::ostream& operator<<(ostream& os, const Box& box) {
os << (box.l * box.b * box.h);
return os;
}
private:
int l, b, h;
};
Upvotes: 1
Reputation: 118017
The member function:
ostream& operator<<(ostream& os);
would be useful in this case:
boxobject << os;
which is rarely what you want to do. Instead, you need this free function:
std::ostream& operator<<(std::ostream& os, const Box& inb) {
os << (inb.l * inb.b * inb.h);
return os;
}
Upvotes: 5