C++ Operator Overloading | Unary, Binary, Stream Insertion and Extraction Operators


This complete tutorial on C++ Operator Overloading explains how to give special meaning to operators for user-defined classes. It covers unary operators, binary operators, and overloading stream insertion (<<) and extraction (>>) operators. Following best practices, this tutorial helps write intuitive and reusable object-oriented code.

Operator Overloading – Complete Tutorial

1. What is Operator Overloading?

Operator overloading allows user-defined classes to define the behavior of operators like +, -, *, <<, >>, etc.

  1. Makes objects behave like built-in types
  2. Improves code readability and reusability

2. Unary Operator Overloading

Unary operators operate on a single operand (e.g., ++, --, -).

Example: Overloading ++ (prefix)


#include <iostream>
using namespace std;

class Counter {
int count;
public:
Counter() : count(0) {}
// Unary operator overloading
void operator++() { count++; }
void display() { cout << count << endl; }
};

int main() {
Counter c;
++c; // calls operator++
c.display(); // Output: 1
}

Notes:

  1. Can overload prefix and postfix versions
  2. Use int parameter for postfix distinction

3. Binary Operator Overloading

Binary operators operate on two operands (e.g., +, -, *, /).

Example: Overloading +


class Point {
int x, y;
public:
Point(int a=0, int b=0) : x(a), y(b) {}
// Binary operator overloading
Point operator+(const Point &p) {
return Point(x + p.x, y + p.y);
}
void display() { cout << x << ", " << y << endl; }
};

int main() {
Point p1(2, 3), p2(4, 5);
Point p3 = p1 + p2; // calls operator+
p3.display(); // Output: 6, 8
}

Notes:

  1. Can be member function or friend function
  2. Returns a new object for binary operations

4. Overloading Stream Insertion (<<) and Extraction (>>) Operators

Used for input/output of class objects.

Example: Stream Insertion (<<)


#include <iostream>
using namespace std;

class Point {
int x, y;
public:
Point(int a=0, int b=0) : x(a), y(b) {}
friend ostream& operator<<(ostream &out, const Point &p) {
out << p.x << ", " << p.y;
return out;
}
};

int main() {
Point p(10, 20);
cout << p << endl; // Output: 10, 20
}

Example: Stream Extraction (>>)


#include <iostream>
using namespace std;

class Point {
int x, y;
public:
friend istream& operator>>(istream &in, Point &p) {
in >> p.x >> p.y;
return in;
}
void display() { cout << x << ", " << y << endl; }
};

int main() {
Point p;
cin >> p; // Input: 5 10
p.display(); // Output: 5, 10
}

Notes:

  1. friend function required for << and >> overloading
  2. Improves readability and integration with streams

Best Practices

  1. Overload operators only when it makes logical sense
  2. Keep operator behavior intuitive
  3. Prefer member functions for unary operators
  4. Prefer friend functions for binary operators and streams
  5. Avoid overloading operators in ways that confuse users

Common Mistakes

  1. Returning void instead of object/reference for binary operators
  2. Overloading operators for unrelated operations
  3. Not handling const correctness
  4. Forgetting to pass ostream/istream by reference for stream operators

Summary

In this chapter, you learned C++ Operator Overloading, including:

  1. Unary operators (++, --, -)
  2. Binary operators (+, -, *, etc.)
  3. Stream insertion (<<) and extraction (>>)
  4. Best practices and common pitfalls

Operator overloading helps write clean and intuitive code that treats objects like primitive data types.