class Complex
{
private:
    double real, imag;
public:
    Complex(double r = 0, double i = 0) : real(r), imag(i) {}
    Complex operator+(const Complex& other)
    {
        return Complex(real + other.real, imag + other.imag);
    }
    friend ostream& operator<<(ostream& out, const Complex& c)
    {
        out << c.real << " + " << c.imag << "i";
        return out;
    }
};
// Complex a(3,4), b(1,2); cout << (a + b);  --> 4 + 6i

Operators that CANNOT be overloaded: :: (scope resolution), . (member access), .* (pointer-to-member access), ?: (ternary), sizeof

Why overload operators at all?

Without overloading, combining two objects requires an awkward function call: addComplex(a, b) instead of the natural a + b. Overloading lets user-defined types read and behave like built-in types.

Full worked example, with comparison operator too

#include <iostream>
using namespace std;

class Complex
{
private:
    double real, imag;

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

    Complex operator+(const Complex& other)          // binary operator, member function
    {
        return Complex(real + other.real, imag + other.imag);
    }

    bool operator==(const Complex& other)             // comparison operator
    {
        return (real == other.real) && (imag == other.imag);
    }

    friend ostream& operator<<(ostream& out, const Complex& c);   // needs friend -- see below
};

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

int main()
{
    Complex a(3, 4), b(1, 2);
    Complex sum = a + b;              // calls operator+
    cout << sum << endl;              // 4 + 6i, calls operator<<
    cout << (a == b) << endl;         // 0 (false)
    return 0;
}

Why operator<< must be a friend, not a member

a + b works as a member function because the left operand (a) is the object calling operator+. But cout << c puts cout (an ostream) on the LEFT — you can't add a member function to the built-in ostream class, so operator<< must be a free function with friend access to Complex's private data.

Operators that CANNOT be overloaded

:: (scope resolution), . (member access), .* (pointer-to-member access), ?: (ternary), sizeof — these are fixed by the language and always operate on their literal operands, not on overloaded semantics.

Important MCQs

  1. Which operator CANNOT be overloaded in C++?
  2. Function/operator overloading is an example of:
  3. operator<< for a custom class is typically implemented as:
  4. Overloading operator+ between two Complex objects lets you write:

Self-Test Questions

  1. Why does operator+ work as a member function but operator<< cannot?