




Study with the several resources on Docsity
Earn points by helping other students or get them with a premium plan
Prepare for your exams
Study with the several resources on Docsity
Earn points to download
Earn points by helping other students or get them with a premium plan
How to overload the + operator in c++ for complex numbers and strings. It covers the implementation of member and non-member functions, function prototypes, and examples of rudimentary complex and string classes. The document also discusses the differences between operator overloading and function overloading.
Typology: Study notes
1 / 8
This page cannot be seen from the preview
Don't miss anything!





addition of these two numbers is returned back. That returned Complex object is assigned to the c3 Complex object using the default assignment operator (that is created by the C++ compiler automatically).
What happens if we want to add a double number to a complex number (a instance of Complex )? Like the following:
c3 = c1 + d ;
This + operation is driven by the c1 object of Complex while double number d of type double is passed as argument. Therefore, our above written + operator is not useable for this operation of addition. We need to overload + operator for accepting a parameter of type double , i.e. we need to write another operator function. The definition of this newly overloaded + operator is:
Complex Complex :: operator + (double d) { Complex temp ; temp.real = real + d ; // d is added into the real part temp.imag = imag ; return temp ; }
By now, you should have noticed that operator overloading and function overloading are quite similar.
When we write the following statement: c3 = d + c1; The operand on the left of + operator is a double number d. Therefore, this + operation should be driven by (called by) the double number. Until now, we have not written such an operator. Our previously written two + operators were driven by the Complex object. Operator functions, not driven by the class type objects, are kept as friend s to the class. friend is the keyword used to declare such functions. A friend function to a class also has access to the private members of that class.
friend Complex operator + (double d, Complex c) { Complex temp; temp.real = d + c.real; // d is added into the real part of c temp.imag = c.imag; return temp; }
You might have noticed that all the three overloaded + operator functions are accepting and returning variables by value. To make these functions better, we can also use references. So our first member + operator’s prototype can be rewritten as:
Complex& operator + (Complex& c);
Now this operator function is accepting a complex number Complex by reference and returning a reference to the resultant complex number.
As discussed above, in case of assignment, the default assignment operator is used because we have not implemented (overloaded) our own assignment operator (‘ = ’). But in case, we want to perform the following operation where the two operands are added and the resultant is assigned to one of them as: c1 = c1 + c2;
There is one operator ( += ) that can be used to do both the operations of addition and assignment instead of doing these operations separately within operator + and operator =. So we can overload this one operator ( += ) here to make the code more efficient and reduce our work. Therefore, instead of writing: c1 = c1 + c2; We will write: c1 += c2;
We will write our operator += as: void Complex :: operator += ( Complex& c ) { real += c.real; imag += c.imag;
}
Now we are much clear that when an operator function is implemented as a member function, the leftmost operator must be a class object or reference to a class object of the operator’s class. When an operator function is implemented as a non-member function, the left-most operand may be an object of the operator’s class, an object of a different class, or a built-in type. Now we discuss it in a detailed manner. We can always write our operators as non-member functions. As a non-member functions, the binary operators like + gets both the operands as arguments. One thing to take care of while writing non-member functions that they cannot access the private members of classes. Actually, this is just to this reason that we make those non- member functions as friend s to the classes whose private data members are required to be accessed. But the question arises, can we write a non-member operator function without making it a friend of a class. The answer to this question is yes; If there are public member functions to access the private data members of the class then they serve the purpose. In this case of Complex class, let’s say we have two public member functions: double real( ); double imaginary( ); to access the private data members real and imag respectively. Then we can write non-member operator + function as:
concatenate two strings (two String objects) and then assign the resultant string to a new String object. Here is how we will write + operator function.
String String :: operator + ( String &s ) { String temp; // Declared object temp of String type strcpy ( temp.string , "" ); // Initialized the temp with empty string strcat ( temp.string , string ); // Concatenated the driving object’s string to // temp object strcat ( temp.string , s.string ); // Concatenated the argument’s string to the // temp object return temp; // Returned the temp object } As you might have guessed already, the String object on the left will be the one to drive this + operation and the second String object on the left of + will be passed as an argument to this function. Note that we are not doing the error checking here, the size of the resultant string temp may increase the array size 30 ( the array size defined in the class).
Example Program 1 Rudimentary implementation of a class named Complex class to cater complex numbers. A + operator function has been implemented to add two complex numbers. /* This program implements the basic class for complex numbers and demonstrates + operator function */
#include <iostream.h>
class Complex { private : double real ; // Real Part double imag ; // Imaginary Part
public : /* Parameterless Constructor */ Complex ( ) { cout << "\n Parameterless Constructor called ..." ; }
/* Parameterized Constructor */ Complex ( double r, double i ) { cout << "\n Parameterized Constructor called ..."; real = r ; imag = i ; }
/* Setter of real data member */ void real ( double r) { real = r ; }
/* Getter of the real data member */ double real ( ) { return real ; }
/* Setter of the imag data member */ void imaginary ( double i ) { imag = i ; }
/* Getter of the imag data member */ double imaginary ( ) { return imag ; }
/* A Function to display parts of a Complex object */ void display ( ) { cout << "\n\n Displaying parts of complex number ..."; cout << "\n Real Part : " << real << endl ; cout << " Imaginary Part : " << imag << endl ; }
/* Declaration (prototype) of overloaded sum operator */ Complex operator + ( Complex & c2 ) ;
};
Complex Complex :: operator + ( Complex & c1 ) { cout << "\n Operator + called ..."; Complex temp ; temp.real = real + c1.real ; temp.imag = imag + c1.imag ; return temp ; }
m ain ( ) {
#include <iostream.h> #include <string.h>
class String { private :
char string [ 30 ] ; // Array to store string
public :
/* Parameterless Constructor */ String ( ) { strcpy ( string , "" ) ; }
/* Getter function of string */ void getString ( ) { cout << "Enter the String: " ; cin >> string ; }
/* Function to display string */ void displayString ( ) { cout << "The String is : " << string << endl ; }
// Declaration (prototype) of overloaded sum operator
String operator + ( String & s ) ; };
String String :: operator + ( String &s ) { String temp ; strcpy ( temp.string , "" ) ; strcat ( temp.string , string ); strcat ( temp.string , s.string ); return temp; }
void main ( ) { String string1 , string2 ; // Declared two String objects string1.getString ( ) ; // Get string for string1 object string2.getString ( ) ; // Get string for string2 object
String hold = string1 + string2 ; // Concatenate string1 and string2 and store the // result in hold object hold.displayString ( ) ; // Display the string }
The output of the above program is as follows: Enter the String: Operator Enter the String: Overloading The String is : OperatorOverloading
Tips Operator Overloading is quite similar to Function Overloading. There are two types of operators to overload: unary and binary. C++ built-in operators work for built-in (primitve) types but for user defined data types, user has to write his/her own operators. There are some restriction while performing Operator Overloading. For example, only existing C++ operators are overloaded without creating a new one in the language. Also, it should not impact the type, semantics (behavior), arity (number of operands required), precedence and associativity of the operator. For binary member operators, operands on the left drives (calls) the operation. Operator functions written as non-members but friends of the class, get both the operands as their arguments. Operators can be written as non-members and even without making them friends. But this is tedious and less efficient way, therefore, it is not recommended.