Overloading Stream Operators
Stream operators let objects work naturally with cout and cin.
cout << point;
cin >> point;
For custom classes, the compiler does not automatically know how to print or read the object. We define operator<< and operator>>.
Why Use Friend Function?
This is another important viva question.
For printing, the left operand is cout, not your object.
cout << point;
If operator<< were a member of Point, the call would need to look like:
point.operator<<(cout);
That would mean writing:
point << cout;
which is unnatural.
So operator<< is usually written as a non-member function:
ostream& operator<<(ostream& out, const Point& point);
It is often declared as friend so it can access private data directly.
Why Return Stream Reference?
The operator returns ostream& or istream& to support chaining.
cout << p1 << p2;
cin >> p1 >> p2;
Without returning the stream, chaining would break.
Complete Example
#include <iostream>
using namespace std;
class Point {
private:
int x;
int y;
public:
Point(int xValue = 0, int yValue = 0) : x(xValue), y(yValue) {}
friend ostream& operator<<(ostream& out, const Point& point) {
out << "(" << point.x << ", " << point.y << ")";
return out;
}
friend istream& operator>>(istream& in, Point& point) {
in >> point.x >> point.y;
return in;
}
};
int main() {
Point p1(3, 4);
Point p2;
cout << "p1 = " << p1 << endl;
// Example input format: 10 20
// cin >> p2;
cout << "p2 = " << p2 << endl;
return 0;
}
Output:
p1 = (3, 4)
p2 = (0, 0)
Friend Is Not Always Required
friend is used when the operator needs direct access to private members.
If the class already has public getters, a normal non-member function can use those getters instead.
ostream& operator<<(ostream& out, const Point& point) {
// use point.getX() and point.getY()
return out;
}
But in many beginner examples, friend is simpler.
Viva Answer
Stream operators are usually overloaded as non-member functions because the left operand is cout or cin, not the user-defined object. They are often declared as friend functions so they can access private members, and they return the stream by reference to allow chaining.
Quick Check
- Why can
cout << objnot usually be a member function ofobj? - Why does
operator<<returnostream&? - Why does
operator>>take the object by non-const reference?