Open In App

Overloading stream insertion operators in C++

Last Updated : 11 Oct, 2025
Comments
Improve
Suggest changes
129 Likes
Like
Report

Stream operator overloading lets us redefine the input (>>) and output (<<) operators for user-defined classes. This lets custom objects interact with cin and cout like built-in types, making input/output intuitive and readable.

  • By default, << and >> work only with built-in types. Overloading enables their use with user-defined objects.
  • Supports chaining multiple input/output operations in one statement.
C++
#include <iostream>
using namespace std;

class Complex
{
  private:
    int real, imag;

  public:
    Complex(int r = 0, int i = 0) : real(r), imag(i)
    {
    }

    // Overload << and >> as friend functions
    friend ostream &operator<<(ostream &out, const Complex &c);
    friend istream &operator>>(istream &in, Complex &c);
};

// Overload << for output
ostream &operator<<(ostream &out, const Complex &c)
{
    out << c.real << " + i" << c.imag;
    return out;
}

// Overload >> for input
istream &operator>>(istream &in, Complex &c)
{
    in >> c.real >> c.imag;
    return in;
}

int main()
{
    Complex c1;

    cout << "Enter real and imaginary parts: ";
    cin >> c1;

    cout << "The complex number is: " << c1 << endl;

    return 0;
}

Output
Enter real and imaginary parts: The complex number is: 0 + i0

Explanation: This program overloads the >> and << operators to allow easy input and output of Complex objects. It uses friend functions to access private members and format input/output like built-in types.

Rules for Stream Operators Overloading

When overloading stream operators, the following rules must be followed:

  • Always return the stream (ostream& or istream&) by reference to allow chaining of multiple input/output operations.
  • Pass both the stream and the object by reference to avoid unnecessary copying.
  • Declare the parameter as const in the insertion operator (<<) since output operations do not modify the object.
  • Implement the operator as a non-member function, but declare it as a friend if access to private members is required.

Why these operators must be overloaded as global? 

In operator overloading, if an operator is overloaded as a member, then it must be a member of the object on the left side of the operator. For example, consider the statement "ob1 + ob2" (let ob1 and ob2 be objects of two different classes). To make this statement compile, we must overload '+' in a class of 'ob1' or make '+' a global function. 
The operators '<<' and '>>' are called like 'cout << ob1' and 'cin >> ob1'. So if we want to make them a member method, then they must be made members of ostream and istream classes, which is not a good option most of the time. Therefore, these operators are overloaded as global functions with two parameters, cout and object of user-defined class.


Explore