All Courses
OOP: OPERATOR OVERLOADING

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

  1. Why can cout << obj not usually be a member function of obj?
  2. Why does operator<< return ostream&?
  3. Why does operator>> take the object by non-const reference?