C++

Overloading in C++

C++ does not allow a function that adds two integers and return an integer, to add two floats and return a float. Imagine that there is a function to add two integers and return an integer. Would it not be nice to have another function with the same name, that adds but two or even more floats to return a float? Doing so is said to be, overloading the first function.

Arithmetic operators are typically used for arithmetic operations. Is it not nice to have the +, join two strings? Enabling that is said to be overloading the arithmetic addition operator, for strings.

The increment operator, ++ adds 1 to an int or a float. When dealing with pointers, it does not add 1 to the pointer. It makes the pointer point to the next consecutive object in memory. An iterator points to the next object in a linked-list, but the linked-list objects are in different places in memory (not in consecutive regions). Would it not be nice to overload the increment operator for an iterator, to increment but point to the following element, in the linked-list?

This article explains overloading in C++. It is divided into two parts: function overloading and operator overloading. Having already basic knowledge in C++ is necessary to understand the rest of the article.

Article Content

Function Overloading

The following function adds two ints and returns an int:

int add(int no1, int no2)
    {
        int sum = no1 + no2;
        return sum;
    }

The prototype of this function is:

    int add(int no1, int no2);

The prototype of a function in the header of the function, ending with a semicolon. The following function with the same name, but with a different prototype, would add three floats and return a float:

float add(float no1, float no2, float no3)
    {
        float sum = no1 + no2 + no3;
        return sum;
    }

How does the compiler differentiate which function to call, since two or more functions have the same name? The compiler uses the number of arguments and argument types to determine which function to call. The parameter list of overloaded functions should differ in their number and/or parameter types. So, the function call,

int sm = add(2, 3);

would call the integer function, while the function call,

float sme = add(2.3, 3.4, 2.0);

would call the float function. Note: there are situations where the compiler will reject an overloaded function when the number of arguments is the same but of different types! – Reason: – see later.

The following program puts the above code segments into action:

#include <iostream>
using namespace std;

int add(int no1, int no2)
    {
        int sum = no1 + no2;
        return sum;
    }

float add(float no1, float no2, float no3)
    {
        float sum = no1 + no2 + no3;
        return sum;
    }

int main()
{
    int sm = add(2, 3);
    cout<<sm<<'\n';
    float sme = add(2.3, 3.4, 2.0);
    cout<<sme<<'\n';
   
    return 0;
}

The output is:
5
7.7

Operator Overloading

Arithmetic operators are used to overload operations in class types. An iterator is a class type. The increment and decrement operators are used to overload operations for an iterator.

Example String Class Operator Overloading

This section provides an example, where + is overloaded for a simply designed string class, called a spring class. + concatenates the literals of two string objects, returning a new object with the concatenated literals. Concatenating two literals means joining the second literal to the end of the first literal.

Now, C++ has a special member function for all classes, called the operator. The programmer can use this special function to overload operators, such as +. The following program shows the overloading of the + operator for two strings.

#include <iostream>
using namespace std;

class spring
    {
        public:
        //data members
        char val[100];
        int n;
        char concat[100];
        //member functions
        spring (char arr[])
            {
                for (int i=0; i<100; ++i) {
                    val[i] = arr[i];
                    if (arr[i]  == '\0')
                        break;
                    }
                int i;
                for (i=0; i<100; ++i) if (arr[i]  == '\0') break;
                n = i;
            }
        spring operator+(spring& st) {
                int newLen = n + st.n;
                char newStr[newLen+1];
                for (int i=0; i<n; ++i) newStr[i] = val[i];                
                for (int i=n; i<newLen; ++i) newStr[i] = st.val[i-n];                
                newStr[newLen] = '\0';
                spring obj(newStr);
                return obj;  
            }
    };

int main()
{
    char ch1[] = "I hate you! "; spring str1(ch1);
    char ch2[] = "But she loves you!"; spring str2(ch2);
    char ch3[] = "one"; spring str3(ch3);
    str3 = str1 + str2;
    cout<<str3.val<<'\n';
   
    return 0;
}

The value of str1 is "I hate you! ". The value of str2 is "But she loves you!". The value of str3, which is, str1 + str2, is the output:

"I hate you! But she loves you!"

which is the concatenation of the two string literals. The strings themselves are instantiated objects.

The definition of the operator function is inside the description(definition) of the string class. It begins with the return type, "spring" for "string". The special name, "operator, follow this". After that, there is the symbol of the operator (to be overloaded). Then there is the parameter list, which is actually the operand list. + is a binary operator: meaning it takes a left and a right operand. However, by the C++ specification, the parameter list here has only the right parameter. Then there is the body of the operator function, which mimics the ordinary operator behaviour.

By the C++ specification, the + operator definition takes only the right operand parameter, because the rest of the class description is the left operand parameter.

In the above code, only the operator+() function definition, is concerned with the + overloading. The rest of the code for the class is normal coding. Inside this definition, the two string literals are concatenated into the array, newStr[]. After that, a new string object is actually created (instantiated), using an argument, newStr[]. At the end of the operator+() function definition, the newly created object, having the concatenated string, is returned.

In the main() function, the addition is done by the statement:

str3 = str1 + str2;

Where str1, str2 and str3 are string objects that have already been created in main(). The expression, “str1 + str2” with its +, calls the operator+() member function in the str1 object. The operator+() member function in the str1 object uses str2 as its argument and returns the new object with (developed) the concatenated string. The assignment operator (=) of the complete statement, replaces the content (values of variables) of the str3 object, with those of the returned object. In the main() function, after addition, the value of the data member str3.val is no longer "one"; it is the concatenated (addition) string, "I hate you! But she loves you!". The operator+() member function in the str1 object, uses its own object's string literal, and the string literal of its argument, str2 to come up with a joined string literal.

Iterator Operator Overloading

When dealing with the iterator, at least two objects are involved: a linked-list and the iterator itself. In fact, at least two classes are involved: a class from which a linked-list is instantiated, and a class from which an iterator is instantiated.

Linked-list

A diagram for a doubly linked-list object is:

This list has three elements, but there can be more. The three elements here are elements of integers. The first one has the value, 14; the next one has the value, 88; and the last one has the value, 47. Each element here consists of three consecutive locations.

This is unlike the array, where each element is one location, and all the array elements are in consecutive locations. Here, the different elements are in different places in the memory series, but each element consists of three consecutive locations.

For each element, the middle location holds the value. The right location has the pointer to the next element. The left location has the pointer to the previous element. For the last element, the right location points to a theoretical end of the list. For the first element, the left location points to a theoretical start of the list.

With the array, the increment operator (++), increments the pointer to point to the physically next location. With the list, the elements are not in consecutive regions in memory. So, the increment operator can be overloaded, move the iterator (pointer) from one element to the logically next element. The same projection applies to the decrement operator (–).

A forward iterator is an iterator that when engaged, points to the next element. A reverse iterator is an iterator, that when engaged, points to the previous element.

Overloading ++ ad —

Overloading of these operators is done in the class description (definition) of the iterator.

The syntax for the prototype of the increment operator overloading, prefix, is

ReturnType operator++();

The syntax for the prototype of the increment operator overloading, postfix, is

ReturnType operator++(int);

The syntax for the prototype of the decrement operator overloading, prefix, is

ReturnType operator--();

The syntax for the prototype of the increment operator overloading, postfix, is

ReturnType operator--(int);

Conclusion

Overloading means giving a different meaning to a function or an operator. Functions are overloaded in the same scope. What differentiates overloaded functions are the number and/or types of parameters in their parameter lists. In some cases, where the number of the parameters is the same, but with different types, the compiler rejects the overloading – see later. Many ordinary operators can be overloaded in classes from which objects are instantiated. This is done by giving a return type, parameter list, and body, to the special function named, operator, in the class description.

About the author

Chrysanthus Forcha

Chrysanthus Forcha

Discoverer of mathematics Integration from First Principles and related series. Master’s Degree in Technical Education, specializing in Electronics and Computer Software. BSc Electronics. I also have knowledge and experience at the Master’s level in Computing and Telecommunications. Out of 20,000 writers, I was the 37th best writer at devarticles.com. I have been working in these fields for more than 10 years.