The World of Mayukh Bose

<< Back to Main Page Mayukh's world: e-mail me | about
Mayukh's World: Operator Overloading With C++ Wednesday, November 26, 2014
Index
  • Introduction
  • What Operators?
  • Rules
  • Assignment Operator
  • More on Assignment
  • Arithmetic Operators
  • Arithmetic with Globals
  • Increment/Decrement
  • Operator-Assignment
  • Unary Operators
  • Relational Operators
  • Bitshift/Extraction
  • Subscript Operator
  • Function Call Operator
  • Bit and Logical Ops
  • Comma Operator
  • Pointer to Member
  • new and delete Ops
  • Credits and Thanks
  • My Free Software
  • Delphi/C++ Builder
  • Pocket PC
  • FreeSpeech Chat
  • C/C++ Freebies
  • Perl
  • Python
  • Ruby
  • C++ Operator Overloading Tutorial e-mail me

    Using a Global function

    In the previous page, we made the addition operator a member of the class Complex. Now let's implement the same functionality using a global function. Since this function will need to access the private members of Complex, we'll need to declare it as a friend function.
    	  class Complex {
    	  private:
    	    double real, imag;
    	  public:
    	    Complex() { real = imag = 0; }
    	    Complex(double r, double i) { real = r; imag = i; }
    	    double GetReal(void) const { return real; }
    	    double GetImag(void) const { return imag; }
    	    Complex& operator=(const Complex& num);
    	    Complex& operator=(const double& d);
    	    friend const Complex operator+(const Complex& first, const Complex& second);
    	  };
    	
    Note the friend keyword. This is needed so that the global function can access the real and imag member variables. The global function is implemented as follows:
    	const Complex operator+(const Complex& first, const Complex& second) {
    	  Complex tmp;
    	  tmp.real = first.real + second.real;
    	  tmp.imag = first.imag + second.imag;
    	  return tmp;
    	}
    	
    You are invited to test drive this new implementation of the + operator to convince yourself that it does the same thing as the operator in the previous page.

    NOTE: If you don't like to use the friend keyword, you could implement public SetReal() and SetImag() functions to access the real and imag members of class Complex. In this case, the code would look like this:
    	  class Complex {
    	  private:
    	    double real, imag;
    	  public:
    	    Complex() { real = imag = 0; }
    	    Complex(int r, int i) { real = r; imag = i; }
    	    double GetReal(void) const { return real; }
    	    double GetImag(void) const { return imag; }
    	    Complex& operator=(const Complex& num);
    	    Complex& operator=(const double& d);
    	    void SetReal(double r) { real = r; }
    	    void SetImag(double i) { imag = i; }
    	    // friend declaration removed. 
    	  };
    	  const Complex operator+(const Complex& first, const Complex& second); // function prototype
    	  ...
    	  ...
    	  const Complex operator+(const Complex &first, const Complex& second) {
    	    Complex tmp;
    	    tmp.SetReal(first.GetReal() + second.GetReal());
    	    tmp.SetImag(first.GetImag() + second.GetImag());
    	    return tmp;
    	  }
    	
    Irrespective of whether we use the first or second implementation, notice that the global function does the same thing as the class member function we implemented in the previous page. So why did we go through the trouble of using a global function then? You'll see in just a little bit. Consider the case where we want to add a Complex number and a double. We can easily implement this as follows:
    	  class Complex {
    	  private:
    	    double real, imag;
    	  public:
    	    Complex() { real = imag = 0; }	
    	    ....
    	    const Complex operator+(const double& d) const;
    	  };
    	  
    	  const Complex Complex::operator+(const double& d) const {
    	    Complex tmp;
    	    tmp.real = real + d;
    	    return tmp;
    	  }
    
    	  int main(void) {
    	    Complex num1(2, 3);
    	    double d = 24.34;
    	    Complex num2;
    	    num2 = num1 + d;
    	    cout << "num2 is " << num2.GetReal() << " + "
    	         << num2.GetImag() << "i" << endl;
    	    return 0;	    
    	  }
    	
    This works pretty well, until we try to do this:
    	   num2 = num1 + d; // WORKS
    	   num2 = d + num1; // DOESN'T WORK
    	
    Suddenly this code doesn't work if the double is the first number. The reason for this is because when we defined the operator overload, it expects the first variable of the addition operator to be of class Complex. There isn't an operator defined yet that takes a double as the first parameter. As it happens, we cannot write this as a member function of class Complex. So what do we do then?

    The answer is, we need to write a global function that takes a double as the first argument and a complex as the second argument. Now you can see why we studied overloading with global functions at the top of this section.
    	  
    	  const Complex operator+(const double& first, const Complex& second) {
    	    return second + first;
    	  }	  
    	
    Bet that was more trivial than you expected. Notice that the global function doesn't do much at all. All it does is reverse the order of the operands. Since we've already defined the operation for Complex + double, the global function merely reuses that code to its advantage to define double + Complex. Also note that this global function didn't need to be declared as friend, since it doesn't need to access any of class Complex's private members. Hence, there is no need to alter the definition of the Complex class. With this function, we can now do:
    	   Complex num1(5, 2), num2;
    	   double d = 24.5;
    	   num2 = num1 + d; // WORKS
    	   num2 = d + num1; // ALSO WORKS NOW
    	
    Now you can practice your skills by overloading some other operators. In the next section, we will study how to overload increment and decrement operators.

    Exercises

    1. Overload the subtraction operator (-) between a Complex and a double and double and Complex.
    2. Overload the multiplication operator (*) for Complex numbers. HINT: For multiplication, the operation is as follows:
    	tmp.real = first.real * second.real - first.imag * second.imag;
    	tmp.imag = first.real * second.imag + second.real * first.imag;
    	


    <<Previous: Arithmetic Operators ^Up to Mayukh's World^ Next: Increment/Decrement >>

    Copyright © 2004 Mayukh Bose. All rights reserved.
    This work may be freely reproduced provided this copyright notice is preserved.
    OPTIONAL: Please consider linking to this website (http://www.mayukhbose.com/) as well.