Operator Overloading in C++

Mannan Ul Haq
0

Operator in C++ like +, -, *, / can operate in data-types like int, float, double, etc as predefined operational meanings. But these operators can't operate in user-defined data-types like objects. Such way of extending the operational functionality of certain operators in C++ is called operator overloading.


Syntax:

return-type(operator)(symbol of operator) (arguments)
{
	// body of code
}


Following is the list of independent overloadable operators:


Operator Name Operator Symbol
Addition +
Subtraction -
Multiplication *
Division /
Modulus (remainder) %
Increment ++
Decrement --
Assignment =
Equality ==
Inequality !=
Greater than >
Less than <
Greater than or equal to >=
Less than or equal to <=
Logical NOT !
Logical AND &&
Logical OR ||
Bitwise NOT ~
Bitwise AND &
Bitwise OR |
Bitwise XOR ^
Bitwise Left Shift <<
Bitwise Right Shift >>
Function call ()
Array subscript []
Member selection .
Member pointer selection ->
Comma ,


There are two types of operator overloading in C++:

1. Overloading Unary Operators:

Unary operators operate on a single operand. They can be overloaded as member functions or non-member functions. When overloading unary operators as member functions, no additional argument is required. Here's an example of pre-increment and post-increment operators as unary operators:

#include <iostream>
using namespace std;

class Counter
{
private:
    int count;

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

    // Pre-increment operator (++counter)
    Counter& operator++()
    {
        count++;
        return *this;
    }

    // Post-increment operator (counter++)
    Counter operator++(int)
    {
        Counter temp(count);
        count++;
        return temp;
    }

    int getCount()
    {
        return count;
    }
};

int main()
{
    Counter c1(5);

    // Pre-increment
    ++c1;
    cout << "Pre-increment: " << c1.getCount() << endl; // Output: 6

    // Post-increment
    Counter c2 = c1++;
    cout << "Post-increment: " << c1.getCount() << endl; // Output: 7
    cout << "Post-increment (returned value): " << c2.getCount() << endl; // Output: 6

    return 0;
}

The pre-increment operator (`++c1`) is overloaded as a member function of the `Counter` class. It increments the `count` member variable directly and returns a reference to the updated object. This allows us to increment the counter and obtain the updated value in a single statement.

The post-increment operator (`c1++`) is also overloaded as a member function. However, it takes an additional dummy integer parameter (int) to differentiate it from the pre-increment operator. Inside the post-increment operator, a temporary `Counter` object (`temp`) is created with the current `count` value. Then, the `count` member variable is incremented. Finally, the temporary object is returned by value, representing the counter value before the increment operation.

2. Overloading Binary Operators:

Binary operators operate on two operands. They can be overloaded as member functions or non-member functions. 

Overloading as Member Function:

When overloading binary operators as member functions, the left operand must be class object, and the right operand is provided as a parameter. Here's an example of overloading the addition (`+`) operator:

class Point
{
private:
    int x, y;

public:
    Point(int xVal, int yVal)
    {
        x = xVal;
        y = yVal;
    }

    Point operator+(const Point& other)
    {
        return Point(x + other.x, y + other.y);
    }
};

int main()
{
    Point p1(2, 3);
    Point p2(4, 5);
    Point p3 = p1 + p2;
    // p3.x is 6, p3.y is 8

    return 0;
}

In the example above, the addition operator is overloaded as a member function of the `Point` class. It performs element-wise addition of the `x` and `y` coordinates of two `Point` objects and returns a new `Point` object.

Overloading as Non-member Function:

Member functions cannot be defined, if left operand of operation is not class object for example: (2 + object). Therefore, non-member functions can be used for such operations. Non-member cannot be defined inside the class. They cannot access the private data members of a class.

Here's an example of binary overloading using a non-member function:

#include <iostream>
using namespace std;

class MyClass
{
private:
    int value;

public:
    MyClass(int val)
    {
        value = val;
    }

    int getValue()
    {
        return value;
    }
};

MyClass operator*(const int num, const MyClass& obj)
{
    int product = num * obj.getValue();
    return MyClass(product);
}

int main()
{
    MyClass obj1(5);
    MyClass result = 2 * obj1;
    cout << "Result: " << result.getValue() << endl;  // Output: 15

    return 0;
}

You can also achieve the same functionality as a friend function:

#include <iostream>
using namespace std;

class MyClass
{
private:
    int value;

public:
    MyClass(int val)
    {
        value = val;
    }
    friend MyClass operator+(const MyClass& obj1, const MyClass& obj2);
};

MyClass operator+(const MyClass& obj1, const MyClass& obj2)
{
    int sum = obj1.value + obj2.value;
    return MyClass(sum);
}

int main()
{
    MyClass obj1(10);
    MyClass obj2(20);
    MyClass result = obj1 + obj2;
    cout << "Result: " << result.value << endl;  // Output: 30

    return 0;
}

 

Tags

Post a Comment

0Comments

Post a Comment (0)

#buttons=(Accept !) #days=(20)

Our website uses cookies to enhance your experience. Check Now
Accept !