Operator Overloading in C++

Last Updated : 17 Jan, 2026

Operator overloading means giving a new meaning to an operator (like +, -, *, []) when it is used with objects.

  • With operator overloading, we can make operators work for user defined classes structures.
  • It is an example of compile-time polymorphism.

Example: In this example, the + operator is overloaded to add two Number objects.

C++
#include <iostream>
using namespace std;

struct Number
{
    int value;

    Number(int v)
    {
        value = v;
    }

    // Overload + operator
    Number operator+(const Number &n)
    {
        return Number(value + n.value);
    }

    void display()
    {
        cout << value << endl;
    }
};

int main()
{
    Number n1(5), n2(10);
    Number n3 = n1 + n2;
    n3.display();
}

Output
15

Why use Operator Overloading?

  • Allows objects to behave like basic data types.
  • Useful for mathematical objects like Complex numbers and Vectors.
  • Reduces the need for extra function calls.

Operator Functions vs Normal Functions

Feature

Operator Function

Normal Function

Syntax

Uses operator keyword

Standard function name

Invocation

Triggered by using an operator

Called explicitly by name

Purpose

Redefines behavior of operators

Performs defined actions

Example

operator+()

add()

Operators That Cannot Be Overloaded

The following operators cannot be overloaded in C++:

  1. sizeof
  2. typeid
  3. Scope resolution (::)
  4. Class member access operators (. and .*)
  5. Ternary / conditional operator (?:)

Why These Operators Cannot Be Overloaded?

1. sizeof Operator

  • Evaluated at compile time
  • Used internally for memory layout and pointer arithmetic
  • Overloading would break fundamental language behavior

2. typeid Operator

  • Used for runtime type identification
  • Must uniquely identify a type
  • Altering its meaning would break RTTI and polymorphism guarantees

3. Scope resolution (::) Operator

  • Works on names, not values
  • Fully resolved at compile time
  • There is no syntax to intercept or overload name resolution

4. Class Member Access Operators (. and .*)

  • Implicitly used by the compiler to access members
  • Overloading would break object access semantics

The importance and implicit use of class member access operators can be understood through the following example:

C++
#include <iostream>
using namespace std;

class Complex
{
  private:
    int real;
    int imaginary;

  public:
    Complex(int real, int imaginary)
    {
        this->real = real;
        this->imaginary = imaginary;
    }
    void print()
    {
        cout << real << " + i" << imaginary;
    }
    Complex operator+(Complex c2)
    {
        Complex c3(0, 0);
        c3.real = this->real + c2.real;
        c3.imaginary = this->imaginary + c2.imaginary;
        return c3;
    }
};
int main()
{
    Complex c1(3, 5);
    Complex c2(2, 4);
    Complex c3 = c1 + c2;
    c3.print();
    return 0;
}

Output
5 + i9

Explanation:

  • "c1 + c2" is translated internally to "c1.operator+(c2)"
  • The dot operator is implicitly required to invoke member functions
  • Since this operator is fundamental to object access, it cannot be overloaded

5. Ternary or conditional (?:) Operator

  • Evaluates only one of the two expressions based on a condition
  • Function calls cannot enforce short-circuit evaluation
  • Overloading would break conditional execution guarantees

Important Points About Operator Overloading

  • At least one operand must be a user-defined type
  • Operators can be overloaded as member or non-member functions
  • Some operators (like conversion operators) must be member functions

Conversion Operator Example:

C++
#include <iostream>
using namespace std;

class Fraction
{
private:
    int num, den;

public:
    Fraction(int n, int d)
    {
        num = n;
        den = d;
    }

    // Conversion operator
    operator float() const
    {
        return float(num) / float(den);
    }
};

int main()
{
    Fraction f(2, 5);
    float val = f;
    cout << val << endl;
}

Output
0.4

Note: Conversion operators must be member functions.

Conversion Constructors

Any constructor that can be called with a single argument acts as a conversion constructor and enables implicit type conversion.

C++
#include <iostream>
using namespace std;

class Point
{
  private:
    int x, y;

  public:
    Point(int i = 0, int j = 0)
    {
        x = i;
        y = j;
    }
    void print()
    {
        cout << "x = " << x << ", y = " << y << '\n';
    }
};

int main()
{
    Point t(20, 20);
    t.print();
    t = 30;
    t.print();
    return 0;
}
Try it on GfG Practice
redirect icon

Output
x = 20, y = 20
x = 30, y = 0
Comment