The Wayback Machine - https://web.archive.org/web/20241121040358/https://www.geeksforgeeks.org/operator-overloading-cpp/
Open In App

Operator Overloading in C++

Last Updated : 11 Oct, 2024
Summarize
Comments
Improve
Suggest changes
Like Article
Like
Save
Share
Report
News Follow

in C++, Operator overloading is a compile-time polymorphism. It is an idea of giving special meaning to an existing operator in C++ without changing its original meaning.

In this article, we will further discuss about operator overloading in C++ with examples and see which operators we can or cannot overload in C++.

C++ Operator Overloading

C++ has the ability to provide the operators with a special meaning for a data type, this ability is known as operator overloading. Operator overloading is a compile-time polymorphism. For example, we can overload an operator ‘+’ in a class like String so that we can concatenate two strings by just using +. Other example classes where arithmetic operators may be overloaded are Complex Numbers, Fractional Numbers, Big integers, etc.

Example:

int a;
float b,sum;
sum = a + b;

Here, variables “a” and “b” are of types “int” and “float”, which are built-in data types. Hence the addition operator ‘+’ can easily add the contents of “a” and “b”. This is because the addition operator “+” is predefined to add variables of built-in data type only. 

Implementation:

C++
// C++ Program to Demonstrate the 
// working/Logic behind Operator
// Overloading
class A {
    statements;
};

int main()
{
    A a1, a2, a3;

    a3 = a1 + a2;

    return 0;
}

To fully master operator overloading and other advanced OOP techniques, our Complete C++ Course provides detailed tutorials with practical examples.


In this example, we have 3 variables “a1”, “a2” and “a3” of type “class A”. Here we are trying to add two objects “a1” and “a2”, which are of user-defined type i.e. of type “class A” using the “+” operator. This is not allowed, because the addition operator “+” is predefined to operate only on built-in data types. But here, “class A” is a user-defined type, so the compiler generates an error. This is where the concept of “Operator overloading” comes in.

Now, if the user wants to make the operator “+” add two class objects, the user has to redefine the meaning of the “+” operator such that it adds two class objects. This is done by using the concept of “Operator overloading”. So the main idea behind “Operator overloading” is to use C++ operators with class variables or class objects. Redefining the meaning of operators really does not change their original meaning; instead, they have been given additional meaning along with their existing ones.

Example of Operator Overloading in C++

C++
// C++ Program to Demonstrate
// Operator Overloading
#include <iostream>
using namespace std;

class Complex {
private:
    int real, imag;

public:
    Complex(int r = 0, int i = 0)
    {
        real = r;
        imag = i;
    }

    // This is automatically called when '+' is used with
    // between two Complex objects
    Complex operator+(Complex const& obj)
    {
        Complex res;
        res.real = real + obj.real;
        res.imag = imag + obj.imag;
        return res;
    }
    void print() { cout << real << " + i" << imag << '\n'; }
};

int main()
{
    Complex c1(10, 5), c2(2, 4);
    Complex c3 = c1 + c2;
    c3.print();
}

Output
12 + i9

Difference between Operator Functions and Normal Functions

Operator functions are the same as normal functions. The only differences are, that the name of an operator function is always the operator keyword followed by the symbol of the operator, and operator functions are called when the corresponding operator is used. 

Example

C++
#include <iostream>
using namespace std;
class Complex {
private:
    int real, imag;

public:
    Complex(int r = 0, int i = 0)
    {
        real = r;
        imag = i;
    }
    void print() { cout << real << " + i" << imag << endl; }
    // The global operator function is made friend of this
    // class so that it can access private members
    friend Complex operator+(Complex const& c1,
                             Complex const& c2);
};
Complex operator+(Complex const& c1, Complex const& c2)
{
    return Complex(c1.real + c2.real, c1.imag + c2.imag);
}
int main()
{
    Complex c1(10, 5), c2(2, 4);
    Complex c3
        = c1
          + c2; // An example call to &quot;operator+&quot;
    c3.print();
    return 0;
}

Output
12 + i9

Can We Overload All Operators? 

Almost all operators can be overloaded except a few. Following is the list of operators that cannot be overloaded. 

sizeof
typeid
Scope resolution (::)
Class member access operators (.(dot), .* (pointer to member operator))
Ternary or conditional (?:)

Operators that can be Overloaded in C++

We can overload

  • Unary operators
  • Binary operators
  • Special operators ( [ ], (), etc)

But, among them, there are some operators that cannot be overloaded. They are

  • Scope resolution operator [Tex](::)[/Tex]
  • Member selection operator                             
  • Member selection through  *

Pointer to a member variable

  • Conditional operator [Tex](?:)[/Tex]
  • Sizeof operator  sizeof()
Operators that can be overloadedExamples
Binary Arithmetic+, -, *, /, %
Unary Arithmetic +, -, ++, —
Assignment=, +=,*=, /=,-=, %=
Bitwise& , | , << , >> , ~ , ^
De-referencing(->)
Dynamic memory allocation,
De-allocation
New, delete 
Subscript[ ]
Function call ()
Logical &,  | |, !
Relational>, < , = =, <=, >=

Why can’t the above-stated operators be overloaded?

1. sizeof Operator

This returns the size of the object or datatype entered as the operand. This is evaluated by the compiler and cannot be evaluated during runtime. The proper incrementing of a pointer in an array of objects relies on the sizeof operator implicitly. Altering its meaning using overloading would cause a fundamental part of the language to collapse.

2. typeid Operator

This provides a CPP program with the ability to recover the actually derived type of the object referred to by a pointer or reference. For this operator, the whole point is to uniquely identify a type. If we want to make a user-defined type ‘look’ like another type, polymorphism can be used but the meaning of the typeid operator must remain unaltered, or else serious issues could arise.

3. Scope resolution (::) Operator

This helps identify and specify the context to which an identifier refers by specifying a namespace. It is completely evaluated at runtime and works on names rather than values. The operands of scope resolution are note expressions with data types and CPP has no syntax for capturing them if it were overloaded. So it is syntactically impossible to overload this operator.

4. Class member access operators (.(dot), .* (pointer to member operator))

The importance and implicit use of class member access operators can be understood through the following example:

Example:

C++
// C++ program to demonstrate operator overloading
// using dot operator
#include <iostream>
using namespace std;

class ComplexNumber {
private:
    int real;
    int imaginary;

public:
    ComplexNumber(int real, int imaginary)
    {
        this->real = real;
        this->imaginary = imaginary;
    }
    void print() { cout << real << " + i" << imaginary; }
    ComplexNumber operator+(ComplexNumber c2)
    {
        ComplexNumber c3(0, 0);
        c3.real = this->real + c2.real;
        c3.imaginary = this->imaginary + c2.imaginary;
        return c3;
    }
};
int main()
{
    ComplexNumber c1(3, 5);
    ComplexNumber c2(2, 4);
    ComplexNumber c3 = c1 + c2;
    c3.print();
    return 0;
}

Output
5 + i9

Explanation:

The statement ComplexNumber c3 = c1 + c2; is internally translated as ComplexNumber c3 = c1.operator+ (c2); in order to invoke the operator function. The argument c1 is implicitly passed using the ‘.’ operator. The next statement also makes use of the dot operator to access the member function print and pass c3 as an argument. 

Besides, these operators also work on names and not values and there is no provision (syntactically) to overload them.

5. Ternary or conditional (?:) Operator

The ternary or conditional operator is a shorthand representation of an if-else statement. In the operator, the true/false expressions are only evaluated on the basis of the truth value of the conditional expression. 

conditional statement ? expression1 (if statement is TRUE) : expression2 (else)

A function overloading the ternary operator for a class say ABC using the definition

ABC operator ?: (bool condition, ABC trueExpr, ABC falseExpr);

would not be able to guarantee that only one of the expressions was evaluated. Thus, the ternary operator cannot be overloaded.

Important Points about Operator Overloading 

1) For operator overloading to work, at least one of the operands must be a user-defined class object.

2) Assignment Operator: Compiler automatically creates a default assignment operator with every class. The default assignment operator does assign all members of the right side to the left side and works fine in most cases (this behavior is the same as the copy constructor). See this for more details.

3) Conversion Operator: We can also write conversion operators that can be used to convert one type to another type. 

Example: 

C++
// C++ Program to Demonstrate the working
// of conversion operator
#include <iostream>
using namespace std;
class Fraction {
private:
    int num, den;

public:
    Fraction(int n, int d)
    {
        num = n;
        den = d;
    }

    // Conversion operator: return float value of fraction
    operator float() const
    {
        return float(num) / float(den);
    }
};

int main()
{
    Fraction f(2, 5);
    float val = f;
    cout << val << '\n';
    return 0;
}

Output
0.4

Overloaded conversion operators must be a member method. Other operators can either be the member method or the global method.

4) Any constructor that can be called with a single argument works as a conversion constructor, which means it can also be used for implicit conversion to the class being constructed. 

Example:

C++
// C++ program to demonstrate can also be used for implicit
// conversion to the class being constructed
#include <iostream>
using namespace std;

class Point {
private:
    int x, y;

public:
    Point(int i = 0, int j = 0)
    {
        x = i;
        y = j;
    }
    void print()
    {
        cout << "x = " << x << ", y = " << y << '\n';
    }
};

int main()
{
    Point t(20, 20);
    t.print();
    t = 30; // Member x of t becomes 30
    t.print();
    return 0;
}

Output
x = 20, y = 20
x = 30, y = 0

Quiz on Operator Overloading



Previous Article
Next Article

Similar Reads

Operator Overloading '<<' and '>>' operator in a linked list class
Prerequisite: Operator Overloading in C++, Linked List in C++ C++ comes with libraries that provide ways for performing Input and Output. In C++, Input and Output are performed as a sequence of bytes, also known as streams. Input and Output stream are managed by the iostream library. cin and cout are the standard objects for the input stream and ou
4 min read
C++ | Operator Overloading | Question 10
Which of the following operator functions cannot be global, i.e., must be a member function. (A) new (B) delete (C) Conversion Operator (D) All of the above Answer: (C) Explanation: new and delete can be global, see following example. #include #include #include using namespace std; class Myclass { int x; public: friend void* operator new(size_t siz
1 min read
Increment (++) and Decrement (--) Operator Overloading in C++
Operator overloading is a feature in object-oriented programming which allows a programmer to redefine a built-in operator to work with user-defined data types. Why Operator Overloading? Let's say we have defined a class Integer for handling operations on integers. We can have functions add(), subtract(), multiply() and divide() for handling the re
4 min read
C++ program to compare two Strings using Operator Overloading
Pre-requisite: Operator Overloading in C++Given two strings, how to check if the two strings are equal or not, using Operator Overloading. Examples: Input: ABCD, XYZ Output: ABCD is not equal to XYZ ABCD is greater than XYZ Input: Geeks, Geeks Output: Geeks is equal to Geeks Approach: Using binary operator overloading. Declare a class with a string
3 min read
Matrix operations using operator overloading
Pre-requisite: Operator OverloadingGiven two matrix mat1[][] and mat2[][] of NxN dimensions, the task is to perform Matrix Operations using Operator Overloading.Examples: Input: arr1[][] = { {1, 2, 3}, {4, 5, 6}, {1, 2, 3}}, arr2[][] = { {1, 2, 3}, {4, 5, 16}, {1, 2, 3}} Output: Addition of two given Matrices is: 2 4 6 8 10 22 2 4 6 Subtraction of
13 min read
C++ Logical (&&, ||, !) Operator Overloading
Prerequisites: OperatorsOperator Overloading Logical operators are used for combining two or more conditions or constraints or to complement the evaluation of the original condition in consideration. The result returns a Boolean value, i.e., true or false. In C++, there are 3 logical operators: Logical AND (&&): This operator returns true o
3 min read
C++ Bitwise Operator Overloading
Prerequisites: Operator OverloadingBitwise Operator in C/C++ In C++, there are a total of six bitwise operators. The six bitwise operators are bitwise AND (&), bitwise OR (|), bitwise XOR (^), left shift (<<), right shift (>>), and bitwise NOT (~). The & (bitwise AND) in C++ takes two numbers as operands and does AND on every bi
7 min read
Typecast Operator Overloading in C++
In C++, the typecast operator can be overloaded to customize the behavior of casting operators to define how user-defined data types can be converted into other types. This enables developers to define how instances of a class are converted to other types, providing more control over implicit type conversions. By overloading typecast operators, dev
6 min read
Overloading New and Delete operator in c++
The new and delete operators can also be overloaded like other operators in C++. New and Delete operators can be overloaded globally or they can be overloaded for specific classes. If these operators are overloaded using member function for a class, it means that these operators are overloaded only for that specific class.If overloading is done out
5 min read
Operator overloading in C++ to print contents of vector, map, pair, ..
Operator overloading is one of the features of Object oriented programming which gives an extra ability to an operator to act on a User-defined operand(Objects). We can take advantage of that feature while debugging the code specially in competitive programming. All we need to do is to overload the stream insertion operator(See this article to unde
3 min read
Rules for operator overloading
In C++, following are the general rules for the things that are not allowed with operator overloading. 1) Only built-in operators can be overloaded. New operators can not be created. 2) Arity of the operators cannot be changed. 3) Precedence and associativity of the operators cannot be changed. 4) Overloaded operators cannot have default arguments
3 min read
Different Ways of Operator Overloading in C++
In C++, operator overloading is the concept that allows us to redefine the behavior of the already existing operator for our class. C++ provides a special function called operator function that can be used to achieve operator overloading. In this article, we will learn the different ways in which we can define the operator function for operator ove
6 min read
Overloading Subscript or array index operator [] in C++
The Subscript or Array Index Operator is denoted by '[]'. This operator is generally used with arrays to retrieve and manipulate the array elements. This is a binary or n-ary operator and is represented in two parts: Postfix/Primary ExpressionExpressionThe postfix expression, also known as the primary expression, is a pointer value such as array or
6 min read
Error: std::endl is of Unknown Type when Overloading Operator <<
In C++, the << operator is commonly overloaded for custom output for user-defined types using streams. However, an issue may arise when using std::endl with an overloaded operator<<. It is shown as the type of std::endl being unknown, leading to compilation errors. In this article, we will learn the cause of this issue and how can we re
4 min read
C++ Assignment Operator Overloading
Prerequisite: Operator Overloading The assignment operator,"=", is the operator used for Assignment. It copies the right value into the left value. Assignment Operators are predefined to operate only on built-in Data types. Assignment operator overloading is binary operator overloading.Overloading assignment operator in C++ copies all values of one
4 min read
Types of Operator Overloading in C++
C++ provides a special function to change the current functionality of some operators within its class which is often called as operator overloading. Operator Overloading is the method by which we can change some specific operators' functions to do different tasks. Syntax: Return_Type classname :: operator op(Argument list){ Function Body} // This
4 min read
deque::operator= and deque::operator[] in C++ STL
Deque or Double ended queues are sequence containers with the feature of expansion and contraction on both the ends. They are similar to vectors, but are more efficient in case of insertion and deletion of elements at the end, and also the beginning. Unlike vectors, contiguous storage allocation may not be guaranteed. deque::operator= This operator
4 min read
Why overriding both the global new operator and the class-specific operator is not ambiguous?
The below section deals about overload resolution as it helps in the fundamentals of overloading and overriding. Predict the output: C/C++ Code #include <iostream> using namespace std; class Gfg { public: void printHello() { cout << "hello gfg-class specific" << endl; } }; void printHello() { cout << "hello gf
5 min read
vector::operator= and vector::operator[ ] in C++ STL
Vectors are same as dynamic arrays with the ability to resize itself automatically when an element is inserted or deleted, with their storage being handled automatically by the container. vector::operator=This operator is used to assign new contents to the container by replacing the existing contents. It also modifies the size according to the new
4 min read
error: call of overloaded ‘function(x)’ is ambiguous | Ambiguity in Function overloading in C++
Pre-requisite: Function Overloading in C++ Function overloading is a feature of object-oriented programming where two or more functions can have the same name but different parameters. When a function name is overloaded with different jobs it is called Function Overloading. Two or more functions are said to be overloaded if they differ in any of th
9 min read
Advantages and Disadvantages of Function Overloading in C++
Function overloading is one of the important features of object-oriented programming. It allows users to have more than one function having the same name but different properties. Overloaded functions enable users to supply different semantics for a function, depending on the signature of functions. Advantages of function overloading are as follows
3 min read
Input/Output Operators Overloading in C++
Operator Overloading is a part of Polymorphism, which enables the feature because of which we can directly use operators with user-defined classes and objects. To read more about this, refer to the article operator overloading in C++. Input/Output Operators(>>/<<) Overloading in C++ We can't directly use the Input/Output Operators (>
2 min read
Function overloading and const keyword
Function overloading is a feature of object-oriented programming where two or more functions can have the same name but different parameters. When a function name is overloaded with different jobs it is called Function Overloading. In Function Overloading “Function” name should be the same and the arguments should be different. Function overloading
5 min read
Overloading stream insertion (<>) operators in C++
In C++, stream insertion operator "<<" is used for output and extraction operator ">>" is used for input. We must know the following things before we start overloading these operators. 1) cout is an object of ostream class and cin is an object of istream class 2) These operators must be overloaded as a global function. And if we want to
2 min read
Function Overloading and float in C++
Although polymorphism is a widely useful phenomena in C++ yet it can be quite complicated at times. For instance consider the following code snippet: C/C++ Code #include&lt;iostream&gt; using namespace std; void test(float s,float t) { cout &lt;&lt; &quot;Function with float called &quot;; } void test(int s, int t) { cout
2 min read
Function Overloading vs Function Overriding in C++
Function Overloading (achieved at compile time) Function Overloading provides multiple definitions of the function by changing signature i.e. changing number of parameters, change datatype of parameters, return type doesn’t play any role. It can be done in base as well as derived class.Example: void area(int a); void area(int a, int b); C/C++ Code
3 min read
Function Overloading and Return Type in C++
Function overloading is possible in C++ and Java but only if the functions must differ from each other by the types and the number of arguments in the argument list. However, functions can not be overloaded if they differ only in the return type. Why is Function overloading not possible with different return types and identical parameters? Function
2 min read
Does overloading work with Inheritance?
If we have a function in base class and another function with the same name in derived class, can the base class function be called from derived class object? This is an interesting question and as an experiment, predict the output of the following C++ program: [GFGTABS] C++ #include <iostream> using namespace std; class Base { public: int f(
5 min read
Function Overloading in C++
Function overloading is a feature of object-oriented programming where two or more functions can have the same name but different parameters. When a function name is overloaded with different jobs it is called Function Overloading. In Function Overloading “Function” name should be the same and the arguments should be different. Function overloading
4 min read
Operands for sizeof operator
The sizeof operator is used to return the size of its operand, in bytes. This operator always precedes its operand. The operand either may be a data-type or an expression. Let's look at both the operands through proper examples. type-name: The type-name must be specified in parentheses. sizeof(type - name) Let's look at the code: C/C++ Code #includ
2 min read
Practice Tags :
three90RightbarBannerImg