Operator Overloading In C++ with Example

Operator Overloading In C++ with Example

With the use of examples, we will learn about operator overloading in this tutorial.

We can adapt operators in C++ to work with user-defined classes. This means that C++ has the ability—known as operator overloading—to give the operators a special meaning for a particular data type.

For instance, by overloading the “+” operator in a class like String, we can concatenate two strings with merely the “+” symbol.

Complex numbers, fractional numbers, big integers, and other sample classes are examples of classes where arithmetic operators may be overloaded.

Operator behavior for user-defined types like objects and structures can be modified in C++. Operator overloading is the term for this. For instance,

Assume we’ve constructed three objects, c1, c2, and c3, which belong to the Complex class, which stands for complex numbers.

We can alter the + operator’s functionality thanks to operator overloading, which enables us to use it to add the complex numbers c1 and c2 by writing the following code:

result = c1 + c2;

as opposed to anything like

result = c1.addNumbers(c2);

This makes our code logical and straightforward to comprehend.

The use of operator overloading is not permitted for basic data types like int, float, char, and so forth.

Overloading Operators in C++ Syntax

We employ a unique operator function to overload an operator. Within the class or structure whose objects or variables we want the overloaded operator to interact with, we declare the function.

class className {
    ... .. ...
    public
       returnType operator symbol (arguments) {
           ... .. ...
       } 
    ... .. ...
};

Here,

  • The function’s return type is returnType.
  • A keyword is an operator.
  • We want to overload the operator sign. such as +,, -, ++, etc.
  • The function’s arguments are the ones supplied to it.

Unary Operator Operator Overloading

Unary operators use only one operand. Unary operators include the operators for increment and decrement, respectively.

Example1: ++ Operator (Unary Operator) Overloading

// Overload ++ when used as prefix

#include <iostream>
using namespace std;

class Count {
   private:
    int value;

   public:

    // Constructor to initialize count to 5
    Count() : value(5) {}

    // Overload ++ when used as prefix
    void operator ++ () {
        ++value;
    }

    void display() {
        cout << "Count: " << value << endl;
    }
};

int main() {
    Count count1;

    // Call the "void operator ++ ()" function
    ++count1;

    count1.display();
    return 0;
}

Output

Count: 6

Here, the void operator ++ () is invoked when we use the command ++count1;. As a result, the object count1’s value property goes up by 1.

Note: When we overload operators, we are free to use them however we see fit. For instance, we could have increased the value by 100 using ++.
However, this complicates and makes it challenging to comprehend our code. As programmers, it is our responsibility to employ operator overloading correctly, consistently, and logically.

The above example only works when ++ is used as a prefix. This syntax is used to make ++ work as a postfix.

void operator ++ (int) {
    // code
}

Take note of the int included in the parenthesis. It’s not a function argument; it’s the syntax for utilizing unary operators as postfix.

Example 2: ++ Operator (Unary Operator) Overloading

// Overload ++ when used as prefix and postfix

#include <iostream>
using namespace std;

class Count {
   private:
    int value;

   public:

    // Constructor to initialize count to 5
    Count() : value(5) {}


    // Overload ++ when used as prefix
    void operator ++ () {
        ++value;
    }


    // Overload ++ when used as postfix
    void operator ++ (int) {
        value++;
    }

    void display() {
        cout << "Count: " << value << endl;
    }
};

int main() {
    Count count1;

    // Call the "void operator ++ (int)" function
    count1++;
    count1.display();

    // Call the "void operator ++ ()" function
    ++count1;

    count1.display();
    return 0;
}

Output

Count: 6
Count: 7

When ++ is used as both a prefix and a postfix in Example 2, it functions. But if we try to do something like this, it won’t work:

Count count1, result;

// Error
result = ++count1;

This is so because our operator function’s return type is void. By making Count the operator function’s return type, we can find a solution to this issue.

// return Count when ++ used as prefix

Count operator ++ () {
    // code
}

// return Count when ++ used as postfix

Count operator ++ (int) {
   // code
}

Example 3: Return Value from Operator Function (++ Operator)

#include <iostream>
using namespace std;

class Count {
   private:
    int value;

   public
       :
    // Constructor to initialize count to 5
    Count() : value(5) {}

    // Overload ++ when used as prefix
    Count operator ++ () {
        Count temp;

        // Here, value is the value attribute of the calling object
        temp.value = ++value;

        return temp;
    }

    // Overload ++ when used as postfix
    Count operator ++ (int) {
        Count temp;

        // Here, value is the value attribute of the calling object
        temp.value = value++;

        return temp;
    }

    void display() {
        cout << "Count: " << value << endl;
    }
};

int main() {
    Count count1, result;

    // Call the "Count operator ++ ()" function
    result = ++count1;
    result.display();

    // Call the "Count operator ++ (int)" function
    result = count1++;
    result.display();

    return 0;
}

Output

Count: 6
Count: 6

For prefix operator overloading, the following code has been used:

// Overload ++ when used as prefix
Count operator ++ () {
    Count temp;

    // Here, value is the value attribute of the calling object
    temp.value = ++value;

    return temp;
}

The postfix operator overloading code is similarly comparable. You’ll see that we produced the temp object and gave its value to the operator function.

Observe the code, too.

temp.value = ++value;

Because count1 is executing the method in main(), the variable value belongs to the count1 object, whereas temp.value belongs to the temp object.

Operator Overloading in Binary Operators

Two operands are used by binary operators. For instance,

result = num + 9;

In this case, the binary operator + operates on the operands 9 and num.

When we employ the following code to overload the binary operator for user-defined types:

obj3 = obj1 + obj2;

The obj1 object is used to invoke the operator function, and obj2 is supplied as an argument.

Example 4: C++ Binary Operator Overloading

// C++ program to overload the binary operator +
// This program adds two complex numbers

#include <iostream>
using namespace std;

class Complex {
   private:
    float real;
    float imag;

   public:
    // Constructor to initialize real and imag to 0
    Complex() : real(0), imag(0) {}

    void input() {
        cout << "Enter real and imaginary parts respectively: ";
        cin >> real;
        cin >> imag;
    }

    // Overload the + operator
    Complex operator + (const Complex& obj) {
        Complex temp;
        temp.real = real + obj.real;
        temp.imag = imag + obj.imag;
        return temp;
    }

    void output() {
        if (imag < 0)
            cout << "Output Complex number: " << real << imag << "i";
        else
            cout << "Output Complex number: " << real << "+" << imag << "i";
    }
};

int main() {
    Complex complex1, complex2, result;

    cout << "Enter first complex number:\n";
    complex1.input();

    cout << "Enter second complex number:\n";
    complex2.input();

   // complex1 calls the operator function
   // complex2 is passed as an argument to the function
    result = complex1 + complex2;
    result.output();

    return 0;
}

Output

Enter first complex number:
Enter real and imaginary parts respectively: 9 5
Enter second complex number:
Enter real and imaginary parts respectively: 7 6
Output Complex number: 16+11i

This program’s operator function is as follows:

Complex operator + (const Complex& obj) {
    // code
}

Alternatively, we might have written this function as follows:

Complex operator + (Complex obj) {
    // code
}

However,

By referencing the complex2 object rather than creating a duplicate object inside the operator function, utilizing & makes our code more efficient.

Because const prevents the operator function from changing complex2, using it is recommended.

Tips for Avoiding Operator Overloading in C++

In C++, the two overloading operators = and & are present by default. For instance, we can use the = operator directly to duplicate objects that belong to the same class. A new operator function is not required.

Operator precedence and associativity cannot be altered by operator overload. However, parentheses should be used if we want to change the evaluation’s order.

  • In C++, there are 4 operators that can never be overloaded.
  • They are (Specific resolution) (Choice of member)
  • . * (pointer to the function used to pick a member): (Tetrahedral operator)

You may like:

Pointer and Function In C++

Leave a Reply