Operator Overloading In C++ - C++ Programming Tutorial
C++ Course / Polymorphism / Operator Overloading In C++

Operator Overloading In C++

BLUF: Mastering Operator Overloading In C++ is a critical step in becoming a proficient C++ developer. This lesson provides a deep dive into the syntax, performance considerations, and real-world applications of this concept.
Key Performance Insight: Operator Overloading In C++

C++ is renowned for its efficiency. Learn how Operator Overloading In C++ enables low-level control and high-performance computing in the tutorial below.

Operator overloading plays a crucial role in C++ programming. This feature enables compile-time polymorphism, allowing developers to redefine the behavior of specific operators like '+', '-', '==', and '*'.

It allows for the utilization of ' + ', ' - ', ' * ' operators with user-defined class objects, enabling operations to be performed with those objects. Various other examples of classes that can have arithmetic operators overloaded include Fractional Numbers, Big Integers, Complex Numbers, and numerous others.

Syntax:

It has the following syntax:

Example

Return_Type classname :: operator symbol(Argument list) 

{

   //Code to be executed

}// It can be done by declaring the function

In this syntax:

  • Return Type: An overloaded operator should always have a return type.
  • The Overloaded operator may take one or more parameters.
  • Operators can be overridden as member functions or non-member functions (friend functions).
  • Simple Example Using C++ Operator Overloading:

    Example

Example

#include <iostream>

using namespace std; //using standard namespace

class Fract {

   private:

    int a1;

    int b1;

   public:

    Fract() : a1(0), b1(0) {}

    void in() {

        cout << "Enter the numerator: ";

        cin >> a1;

        cout<< "Enter the denominator: ";

        cin >> b1;

    }

    // Overload the * operator

    Fract operator * (const Fract &ob) {

        Fract tem;

        tem.a1 = a1 * ob.a1;

        tem.b1 = b1 * ob.b1;

        return tem;

    }

 

    void out() {

      cout<<"The fraction is  "<< a1<<"/ "<<b1;

    }

};

int main() //main function

{

    Fract Fa1, Fa2, res;

    cout << "Enter the first fraction:n";

    Fa1.in();

    cout << "Enter the second fraction:n";

    Fa2.in();

   // The overloading operator

    res = Fa1 * Fa2;

    res.out();

    return 0;

}

Output:

Output

Enter the first fraction: Enter the numerator : 3

Enter the denominator : 4

Enter the second fraction:nEnter the numerator : 2

Enter the denominator: 5

The fraction is  6/ 20

Explanation:

This C++ program introduces the 'Fract' class, designed to handle fractions, specifically overloading the multiplication operator. Within this class, the attributes 'a1' (representing the numerator) and 'b1' (representing the denominator) are kept private.

The 'operator*' function overloads the multiplication operator to multiply two fractions by multiplying both the numerators and denominators. Within the main function, two fraction objects are instantiated, user input is collected, and the product of the fractions is calculated.

Rules for C++ Operator Overloading:

There are several rules that help to understand operator overloading in C++.

  • If we want to use operator overloading, at least one operand should be a user-defined class object.
  • We may only enable to overload existing operators. We cannot overload new operators.
  • In C++, some of the operators may not be overloaded using the friend function. Although, these operators may be overloaded with the assistance of the member functions.
  • Types of Operator Overloading in C++:

Various forms of operator overloading include the following:

1. Unary Operator Overloading:

In C++, a unary operator overload function is a form of operator overloading that operates on a single operand.

C++ Unary Operator Overloading Example:

Let's consider a scenario to demonstrate the overloading of unary operators in the C++ programming language.

Example

Example

#include <iostream>

using namespace std; //using standard namespace

class Decrement {

private:

    int val;

public:

    // the constructor

    Decrement(int v) : val(v) {}

    // Overload prefix decrement operator (--x)

    Decrement operator--() {

        --val;  // decrement the value

        return *this;  // return val

    }

    // Function to display value

    void display() {

        cout << "The Value: " << val << endl;

    }

};

int main() //main function

{

    Decrement obj(15); // The object initialization

    cout << "The value before decrement: ";

    obj.display();

    --obj; // the prefix operator overloading

    cout << "The value after decrement: ";

    obj.display();

    return 0;

}

Output:

Output

The value before decrement: The Value: 15

The value after decrement: The Value: 14

Explanation:

The provided C++ code is created to overload the prefix decrement operator (--). Within the Decrement class, there exists a private integer member labeled "val" that is initialized through a constructor. The prefix decrement operator is defined using a member function named operator, responsible for reducing the 'val' value by one and then returning the updated object.

2. Binary Operator Overloading

In the C++ binary operator overloading method, it is essential to have precisely one argument available for passing. This type of operator overloading is responsible for executing operations on a pair of operands.

C++ Binary (+) Operator Overloading Example:

Let's consider an illustration to showcase the Binary (+) Operator Overloading in C++.

Example

Example

#include <iostream>

using namespace std; //using standard namespace

class Cmplx {

    float real_num, imag_num;

public:

    // Constructor

    Cmplx(float r = 0.0, float i = 0.0) : real_num(r), imag_num(i) {}

    // Overloading + operator as a member function

    Cmplx operator+(const Cmplx& other) {

        return Cmplx(real_num + other.real_num, imag_num + other.imag_num);

    }

    // Display function

    void display() const {	

        cout << real_num << " + " << imag_num << "i" << endl;

    }

};

int main() //main function

{

    Cmplx a1(4.7, 2.8), a2(3.5, 5.7);

    Cmplx a3 = a1 + a2; // Using overloaded + binary operator

    cout << "Enter the First Cmplex Number: ";

    a1.display();

    cout << "Enter the Second Complex Number: ";

    a2.display();

    cout << "Sum of both Numbers: ";

    a3.display();

    return 0;

}

Output:

Output

Enter the First Cmplex Number: 4.7 + 2.8i

Enter the Second Complex Number: 3.5 + 5.7i

Sum of both Numbers: 8.2 + 8.5i

Explanation:

In this instance, a sophisticated class was selected, incorporating two private attributes, realnum and imagnum. Subsequently, a constructor with parameters and default values was implemented. This constructor initializes the complex numbers as realnum + imagnum * i. Following this, the binary + operator is utilized within the code to display the total of the two complex numbers.

3. Binary Operator Overloading using a Friend Function:

In C++, when implementing binary operator overloading through a friend function, it is essential that the operator overloading function is defined prior to the friend function. Additionally, this function must be declared within the scope of the class. Typically, in a binary operator scenario, the friend function accepts two distinct parameters and alters one parameter using the unary operator.

In this instance, we will demonstrate an example of overloading binary operators in C++ by utilizing a friend function.

Let's consider an illustration to showcase the Binary Operator Overloading through the utilization of the friend function in C++.

Example

Example

#include <iostream>

using namespace std; //Using Standard Namespace

class Factorial_Of_Number {

    int num;

    long long fact;

public:

    //Using Constructor

    Factorial_Of_Number(int n = 1) : num(n) {

        fact = 1;

        for (int i = 1; i <= num; ++i)

            fact *= i;

    }

    // Friend function

    friend Factorial_Of_Number operator*(const Factorial_Of_Number& x, const Factorial_Of_Number& y);

    // Display function

    void display() const {

        cout << "Factorial of " << num << " is: " << fact << endl;

    }

    // Display product

    void displayProduct() const {

        cout << "Product of factorials: " << fact << endl;

    }

};

// Overloaded * operator using friend function

Factorial_Of_Number operator*(const Factorial_Of_Number& x, const Factorial_Of_Number& y) {

    Factorial_Of_Number result;

    result.fact = x.fact * y.fact;

    result.num = x.num * y.num;

    return result;

}

int main() //Main function

{

    Factorial_Of_Number x(5); 

    Factorial_Of_Number y(4); 

    Factorial_Of_Number result = x * y; 

    x.display();

    y.display();

    result.displayProduct();

    return 0;

}

Output:

Output

Factorial of 5 is: 120

Factorial of 4 is: 24

Product of factorials: 2880

Explanation:

In this instance, we are outlining a class named FactorialOfNumber, responsible for computing the factorial of a specified numerical value. Subsequently, we shall implement binary operator overloading by employing a friend function to overload the * operator.

When two instances of a class are multiplied, the friend function retrieves their private factorial values, calculates the product of those factorials, and returns a new object containing the result. The show method is responsible for displaying the factorial values, while the showProduct function is used to present the final output.

Which Operators Can and Cannot Be Overloaded in C++?

When it comes to overloading unary and binary operators in C++, it's important to note that not all operators are overloadable, and certain ones must be left unaltered.

Operators that can be overloaded are those that can be redefined to operate with user-defined types, whereas operators that cannot be overloaded are considered fundamental to the language and cannot be redefined.

Here is a list of operators which cannot be overloaded in C++.

  • Ternary (Conditional) Operator (? :)
  • Member Access (Dot) Operator (.)
  • Pointer-to-Member Operator (.*)
  • Scope Resolution Operator (::)
  • Type Identification Operator (typeid)
  • Size Operator (sizeof)

Operator overloading is achievable with specific operators in C++.

Special Operator Overloading in C++:

There are various operators in C++ which can be overloaded for their use in user-defined datatypes. These include the following set of operators.

  • new: It is used to declare a pointer variable as well as allocate memory to it when the program is being executed.
  • delete: This operator frees up the memory which has been assigned to the pointer variable.
  • (subscript): This operator enables the selection of a particular value from an array.
  • (member access): It permits the selection of the variable members of the class through a pointer.
  • = (assignment): This operator is used to copy data from one object to another object.
  • (function call): This operator gives every object the ability to act as a function.

By overloading these operators, it streamlines the structure of interactions among the objects and enhances the effectiveness and adaptability of the C++ programming ecosystem.

Benefits of Operator Overloading in C++:

Several benefits of operator overloading in C++ are as follows:

  • Improved Clarity: The programmers will have the chance to use a more comprehensible syntax, which increases clarity and understanding of the code due to operator overloading.
  • Increased Maintainability: It allows user-defined types to behave like fundamental types, which reduces issues and provides better maintenance.
  • Support for Reuse of Code: The possibility of applying an operator to other different objects increases the support of reusability.
  • Abstraction and Encapsulation: Operator overloading is a feature of object-oriented programming and is facilitated by the abstraction and encapsulation of data.
  • Drawbacks of Operator Overloading in C++:

Several drawbacks of operator overloading in C++ are as follows:

  • Potential Misuse: It is possible to define overloaded operators in a way that leads to redundancy or makes the implementation harder to follow.
  • Increased Difficulty: Because of the previously defined purpose, overloads may seem to make the application more complex, therefore introducing confusion and additional issues to solve.
  • Limits of Overloading: In C++, there is no possibility to overload every operator, for example, member access operators.
  • Conclusion:

In summary, operator overloading allows customized user-defined data types to mimic predefined types, improving the clarity, versatility, and manageability of code. It permits the customization of operators for specific classes, simplifying the resolution of complex issues.

C++ Operator Overloading MCQs

  1. Can the assignment (=) operator be overloaded in C++?
  • Yes, as a friend function
  • Yes, as a Member Function
  • Yes, but only as a non-member function
  1. Which operators are obligated to be overloaded as class member functions in C++?
  1. Which of the following statements is correct about the friend function operator in C++?
  • They must be defined in the class
  • They can access the private members of a class
  • They are slower than the member functions
  • They can only overload unary operators
  1. What is the purpose of overloading the following operator function?

Bool operator== (const MyClass &obj);

  • Equality Comparison
  • Addition
  • Assignment
  • Logical AND

a) Comparing Equality

  1. Which operators in C++ are eligible for overloading?
  • sizeof

Input Required

This code uses input(). Please provide values below:

Logic Practice
Install Logic Practice
Add to home screen for a faster app-like experience