C++ Operator Overloading: Custom Operators Examples

Explore practical examples of C++ operator overloading with custom operators to enhance your programming skills.
By Jamie

Understanding C++ Operator Overloading

C++ allows developers to redefine the functionality of operators for user-defined types through operator overloading. This feature enhances code readability and allows for intuitive interactions with objects. In this article, we present three diverse examples of C++ operator overloading using custom operators, demonstrating their practical applications.

Example 1: Overloading the + Operator for a Complex Number Class

Context

In mathematical computations, complex numbers are often used. By overloading the + operator, we can easily add two complex numbers using familiar syntax.

#include <iostream>

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

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

    void display() const {
        std::cout << real << " + " << imag << "i" << std::endl;
    }
};

int main() {
    Complex num1(1.5, 2.5);
    Complex num2(3.0, 4.0);
    Complex result = num1 + num2;  // Using overloaded + operator
    result.display();  // Output: 4.5 + 6.5i
    return 0;
}

Notes

  • This example illustrates how operator overloading can simplify the addition of complex numbers.
  • Variations can include overloading other operators like -, *, and / for complete arithmetic functionality.

Example 2: Overloading the << Operator for Custom Output

Context

When working with classes, it is often necessary to display object information. Overloading the << operator allows for easy integration with standard output streams.

#include <iostream>

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

    friend std::ostream& operator<<(std::ostream& os, const Point& point) {
        os << "Point(" << point.x << ", " << point.y << ")";
        return os;
    }
};

int main() {
    Point p(3, 4);
    std::cout << p << std::endl;  // Output: Point(3, 4)
    return 0;
}

Notes

  • This example shows how to create a user-friendly way to output complex objects to the console.
  • You can further customize the output format based on your needs.

Example 3: Overloading the [] Operator for Array-Like Access

Context

For classes that manage collections of data (like a matrix), overloading the [] operator allows users to access elements using array-like syntax, improving usability.

#include <iostream>
#include <vector>

class Matrix {
private:
    std::vector<std::vector<int>> data;
public:
    Matrix(int rows, int cols) : data(rows, std::vector<int>(cols, 0)) {}

    std::vector<int>& operator[](int index) {
        return data[index];
    }

    void display() const {
        for (const auto& row : data) {
            for (int val : row) {
                std::cout << val << " ";
            }
            std::cout << std::endl;
        }
    }
};

int main() {
    Matrix mat(3, 3);
    mat[0][0] = 1;
    mat[1][1] = 2;
    mat[2][2] = 3;
    mat.display();
    return 0;
}

Notes

  • This example demonstrates how to provide intuitive access to elements in a custom data structure.
  • You can expand this example to include bounds checking for safety.