GuideC++

Operator Overloading

OOP Basics / Operator Overloading

Concept Lesson
Intermediate
4 min

Learning Objective

Understand Operator Overloading well enough to explain it, recognize it in C++, and apply it in a small task.

Why It Matters

This concept is part of the foundation that later lessons and projects assume you already understand.

OperatorOverloadingTable Of ContentsOverloadable OperatorsSyntax
Private notes
0/8000

Notes stay private to your browser until account sync is configured.

Guide
1 min read18 headings

Operator Overloading in C++

Table of Contents

  1. Introduction
  2. Syntax
  3. Arithmetic Operators
  4. Comparison Operators
  5. Stream Operators
  6. Assignment Operator
  7. Subscript and Function Call
  8. Friend Functions
  9. Best Practices

Introduction

Operator overloading lets you define how operators work with your custom types.

Vector v1(1, 2), v2(3, 4);
Vector v3 = v1 + v2;  // Uses overloaded +

Overloadable Operators

Can OverloadCannot Overload
+ - * / %:: . .*
== != < > <= >=?: sizeof
<< >>typeid
= [] ()
++ --
new delete

Syntax

As Member Function

class Number {
    int value;
public:
    Number operator+(const Number& other) const {
        return Number(value + other.value);
    }
};

As Non-Member (Friend)

class Number {
    int value;
    friend Number operator+(const Number& a, const Number& b);
};

Number operator+(const Number& a, const Number& b) {
    return Number(a.value + b.value);
}

Arithmetic Operators

class Vector {
    double x, y;
public:
    Vector(double x = 0, double y = 0) : x(x), y(y) {}

    Vector operator+(const Vector& v) const { return Vector(x + v.x, y + v.y); }
    Vector operator-(const Vector& v) const { return Vector(x - v.x, y - v.y); }
    Vector operator*(double s) const { return Vector(x * s, y * s); }
    Vector operator/(double s) const { return Vector(x / s, y / s); }

    Vector operator-() const { return Vector(-x, -y); }  // Unary minus
};

Compound Assignment

Vector& operator+=(const Vector& v) {
    x += v.x; y += v.y;
    return *this;
}

Increment/Decrement

class Counter {
    int value;
public:
    Counter& operator++() { ++value; return *this; }      // Pre
    Counter operator++(int) { Counter t = *this; ++value; return t; }  // Post
};

Comparison Operators

class Date {
    int year, month, day;
public:
    bool operator==(const Date& d) const {
        return year == d.year && month == d.month && day == d.day;
    }
    bool operator!=(const Date& d) const { return !(*this == d); }
    bool operator<(const Date& d) const {
        if (year != d.year) return year < d.year;
        if (month != d.month) return month < d.month;
        return day < d.day;
    }
    bool operator>(const Date& d) const { return d < *this; }
    bool operator<=(const Date& d) const { return !(d < *this); }
    bool operator>=(const Date& d) const { return !(*this < d); }
};

C++20 Spaceship Operator

#include <compare>
class Date {
    auto operator<=>(const Date&) const = default;  // All comparisons!
};

Stream Operators

class Point {
    int x, y;
public:
    friend ostream& operator<<(ostream& os, const Point& p) {
        return os << "(" << p.x << ", " << p.y << ")";
    }

    friend istream& operator>>(istream& is, Point& p) {
        return is >> p.x >> p.y;
    }
};

// Usage
Point p(3, 4);
cout << p << endl;  // (3, 4)
cin >> p;           // Input: 5 6

Assignment Operator

Copy Assignment

class String {
    char* data;
    size_t len;
public:
    String& operator=(const String& other) {
        if (this != &other) {  // Self-assignment check
            delete[] data;
            len = other.len;
            data = new char[len + 1];
            strcpy(data, other.data);
        }
        return *this;
    }
};

Move Assignment (C++11)

String& operator=(String&& other) noexcept {
    if (this != &other) {
        delete[] data;
        data = other.data;
        len = other.len;
        other.data = nullptr;
        other.len = 0;
    }
    return *this;
}

Subscript and Function Call

Subscript []

class Array {
    int* data;
    size_t size;
public:
    int& operator[](size_t i) { return data[i]; }
    const int& operator[](size_t i) const { return data[i]; }
};

Function Call ()

class Adder {
    int value;
public:
    Adder(int v) : value(v) {}
    int operator()(int x) const { return x + value; }
};

Adder add5(5);
cout << add5(10);  // 15

Friend Functions

Use friend when left operand isn't your class:

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

    // 2.0 * complex needs friend
    friend Complex operator*(double d, const Complex& c) {
        return Complex(d * c.real, d * c.imag);
    }
};

Complex c(1, 2);
Complex r = 2.0 * c;  // Works!

Best Practices

✅ Do

// Return reference for compound assignment
T& operator+=(const T& other) { ...; return *this; }

// Implement in terms of compound
T operator+(const T& a, const T& b) { T t = a; return t += b; }

// Const correctness
bool operator==(const T& other) const;

// Self-assignment check
T& operator=(const T& other) {
    if (this != &other) { ... }
    return *this;
}

❌ Don't

// Don't change expected behavior
T operator+(const T& other) { /* don't subtract! */ }

// Don't overload &&, ||, or comma
T operator&&(const T& other);  // Breaks short-circuit

// Don't return references to temporaries
T& operator+(const T& other) { T t = ...; return t; }  // Dangling!

Quick Reference

class T {
public:
    // Arithmetic
    T operator+(const T& r) const;
    T& operator+=(const T& r);
    T operator-() const;          // Unary
    T& operator++();              // Pre
    T operator++(int);            // Post

    // Comparison
    bool operator==(const T& r) const;
    bool operator<(const T& r) const;

    // Assignment
    T& operator=(const T& r);
    T& operator=(T&& r) noexcept;

    // Subscript
    E& operator[](size_t i);

    // Function call
    R operator()(Args...);

    // Stream (friend)
    friend ostream& operator<<(ostream&, const T&);
    friend istream& operator>>(istream&, T&);
};

Compile & Run

g++ -std=c++17 -Wall examples.cpp -o examples && ./examples

Skill Check

Test this lesson

Answer 4 quick questions to lock in the lesson and feed your adaptive practice queue.

--
Score
0/4
Answered
Not attempted
Status
1

Which module does this lesson belong to?

2

Which section is covered in this lesson content?

3

Which term is most central to this lesson?

4

What is the best way to use this lesson for real learning?

Your answers save locally first, then sync when account storage is available.
Practice queue