Function and Operator Overloading in C++

Overloading allows the same name to be used for different purposes — either different function behaviors or different meanings for operators when applied to user-defined types.

Function Overloading

Function overloading allows defining multiple functions with the same name but different parameter lists. The compiler chooses the correct version based on the arguments provided at the call site.

#include <iostream>
using namespace std;

void display(int x) {
    cout << "Integer: " << x << endl;
}

void display(double x) {
    cout << "Double: " << x << endl;
}

void display(string s) {
    cout << "String: " << s << endl;
}

int main() {
    display(10);
    display(3.14);
    display("Hello");
    return 0;
}

Output:

Integer: 10
Double: 3.14
String: Hello

Overloading Based on Number of Parameters:

int multiply(int a, int b)         { return a * b; }
int multiply(int a, int b, int c)  { return a * b * c; }

int main() {
    cout << multiply(3, 4)    << endl;  // 12
    cout << multiply(2, 3, 4) << endl;  // 24
    return 0;
}

Rules for Function Overloading

  • Functions must differ in the number or type of parameters.
  • Difference only in return type is NOT enough — it will cause a compile error.
  • Default arguments can interact with overloading — be careful of ambiguity.

Operator Overloading

C++ allows redefining how operators (+, -, *, ==, etc.) behave for user-defined classes. This makes class objects behave like built-in types.

Syntax:

return_type operator symbol (parameters) {
    // implementation
}

Example — Overloading the + Operator:

#include <iostream>
using namespace std;

class Vector2D {
public:
    int x, y;

    Vector2D(int x, int y) : x(x), y(y) {}

    Vector2D operator+(const Vector2D &v) {
        return Vector2D(x + v.x, y + v.y);
    }

    void show() {
        cout << "(" << x << ", " << y << ")" << endl;
    }
};

int main() {
    Vector2D v1(1, 2);
    Vector2D v2(3, 4);
    Vector2D v3 = v1 + v2;   // calls operator+
    v3.show();
    return 0;
}

Output:

(4, 6)

Overloading == Operator:

class Point {
public:
    int x, y;
    Point(int x, int y) : x(x), y(y) {}

    bool operator==(const Point &p) {
        return (x == p.x && y == p.y);
    }
};

int main() {
    Point p1(3, 5), p2(3, 5), p3(1, 2);
    cout << (p1 == p2 ? "Equal" : "Not Equal") << endl;
    cout << (p1 == p3 ? "Equal" : "Not Equal") << endl;
    return 0;
}

Output:

Equal
Not Equal

Overloading ++ Prefix Operator:

class Counter {
public:
    int count;
    Counter(int c = 0) : count(c) {}

    Counter operator++() {     // prefix ++
        ++count;
        return *this;
    }

    void show() { cout << "Count: " << count << endl; }
};

int main() {
    Counter c(5);
    ++c;
    c.show();   // Count: 6
    return 0;
}

Operators That Can Be Overloaded

Most operators can be overloaded including: +, -, *, /, %, ==, !=, <, >, [], (), <<, >>, ++, --, =

Operators That CANNOT Be Overloaded

  • :: — Scope resolution
  • . — Member access
  • .* — Pointer to member
  • ?: — Ternary operator
  • sizeof

Key Takeaways

  • Function overloading allows multiple functions with the same name but different parameters.
  • Operator overloading gives custom meanings to operators for user-defined types.
  • Overloaded operators make code more natural and readable.
  • The operator keyword is used to define overloaded operators.
  • Not all operators can be overloaded — scope resolution (::) and member access (.) cannot.

Leave a Comment

Your email address will not be published. Required fields are marked *