GIDForums  

Go Back   GIDForums > Computer Programming Forums > C++ Forum
User Name
Password
Register FAQ Members List Calendar Search Today's Posts Mark Forums Read

 
 
Thread Tools Search this Thread Rate Thread
  #1  
Old 20-Oct-2004, 16:05
grscot grscot is offline
New Member
 
Join Date: Oct 2004
Posts: 1
grscot is on a distinguished road

Operator overloading problem


Dear all,

I cannot quite understand the logic behind the notion of operator overloading.
I understand that creating a class, is like creating a new type, therefore we can overload some operators to work with that new type. For example:

CPP / C++ / C Code:
Ratio& Ratio::operator=(const Ratio& r)
{
  num = r.num;
  den = r.den;
  return *this;
} 
This example is absolutely comprehensible but I cannot understand how I have to think, visualize the things in order to implement operator overloading in the *, *= operator, or in the == for instance.
Consider the Ratio class as the following:

CPP / C++ / C Code:
class Ratio
{
  friend Ratio& operator*(const Ratio& x, const Ratio y);
  public:
  Ratio(int =0, int =1);
  Ratio& operator=(const Ratio&);
  
  Ratio& operator*=(const Ratio&);
  private:
  int num, den;
};

Here is the understanding problem:

CPP / C++ / C Code:
Ratio operator*(const Ratio& x, const Ratio& y)
{
 Ratio z(x.num*y.num, x.den*y.den);
 return z;
}

Is this the only way to overload that operator in this example? How one has to think in order to writew the above code? What are the steps involved in order to write the above two lines of code? And secondly in the first example (operator=) the return type is a reference to the Ratio but in the second is not a reference. Why is not a reference. When should we use a reference and when not?

Please bare in mind that I understand the use of friend functions.
Thanks in advance for the help,
grscot
Last edited by LuciWiz : 21-Oct-2004 at 00:32. Reason: Please insert your C code between [c] [/c] tags
  #2  
Old 20-Oct-2004, 17:24
aaroncohn's Avatar
aaroncohn aaroncohn is offline
Regular Member
 
Join Date: Feb 2004
Location: Bay Area, CA.
Posts: 564
aaroncohn is a jewel in the roughaaroncohn is a jewel in the roughaaroncohn is a jewel in the rough
First things first. Please refer to this page for some information on posting C++ code in the forum. Ok, now for the operators...

From what I can see, the only operator that hasn't been overloaded with a reference type for the return value is the implementation of the * operator. This is most likely a typo or a simple mistake. The code that you posted above, though more carefully organized, should look like this...

CPP / C++ / C Code:
class Ratio
{
  public:
    friend Ratio& operator*(const Ratio x, const Ratio y); // This should be public!
    // Also, no reference operators in the parameter list above, since we aren't changing the values of the parameters.
    Ratio(int =0, int =1);
    Ratio& operator=(const Ratio&);
    // Ratio& operator*=(const Ratio&); Woops, you didn't write this function!

  private:
    int num;
    int den;
};

Ratio& Ratio::operator=(const Ratio& r)
{
  num = r.num;
  den = r.den;
  return *this;
}

Ratio& operator*(const Ratio& x, const Ratio& y)
{
  Ratio z(x.num*y.num, x.den*y.den);
  return z;
}
Please take notice that you have defined the = operator to work for setting a Ratio equal to a Ratio. The = operator is already defined by the C language for this type of aggregate operation, therefore, the function wrote already exists, and you didn't need to write it! Ok... the reason you need the reference for your friend function's return type is that you intend to use the function in conjunction with the = operator. Consider the prototype for the = operator.

CPP / C++ / C Code:
class someclass
{
  public:
    someclass& operator=( const someclass &item );
};
As you can see, the incoming parameter is a reference type with a const modifier. This means that you now have the address of item, but you can't change the contents of it. Now consider the following statement...

CPP / C++ / C Code:
int main()
{
  Ratio x, y, z;

  x = y * z;

  return 0;
}
Ok, let's "debug" that statement. Knowing that the set operator goes from right to left when evaluating its operands, we start at the multiplication.

CPP / C++ / C Code:
Ratio& operator*( Ratio x, Ratio y )
{
  Ratio z(x.num*y.num, x.den*y.den); // Multiply all values and use them to initialize a new Ratio.
  return z; // Return the address of the evaluated ratio.
}
.
.
.
// Now the program moves on to the = operator...
// It's already defined by C, but for our purposes, let's see what it's doing!

Ratio& Ratio::operator=( const Ratio &r ) // r comes in from the return type of that operator* function.
{
  num = r.num; 
  den = r.den;

  return *this;
}
So, you can see now that the statement x = y * z; first uses your overloaded operator to multiply y and z into a single Ratio, then it returns the result and takes that result as a parameter for the = operator, which didn't need to be overloaded in the first place, since Ratio = Ratio is valid in C without any extra work by the programmer.

So, to answer your question, it should be quite apparent that a reference is used when you are going to change the value of a variable that is getting passed to the function or when you need the address of a return value to be passed on to another operator, such as the = operator or the [] operator. Hope this helps!
__________________
-Aaron
  #3  
Old 20-Oct-2004, 23:59
aaroncohn's Avatar
aaroncohn aaroncohn is offline
Regular Member
 
Join Date: Feb 2004
Location: Bay Area, CA.
Posts: 564
aaroncohn is a jewel in the roughaaroncohn is a jewel in the roughaaroncohn is a jewel in the rough
Oh, just a quick note: you WILL want to overload the = operator for aggregate copying if your class contains dynamically allocated data. If it doesn't, then it's ok to just use C's convention for copying a class into another class of the same type. However, when you try to copy the contents of a class with dynamically allocated data into another class of the same type, bad things happen. You'll basically have what we call a memory leak. All of the pointers in one class are set to point to memory already pointed to by the class that you copied into it. Therefore, anything that was being pointed to by the class that was copied into is now floating around in limbo, and you can't get it back. The only way to fix a memory leak is to restart your computer, or to be using Unix, where memory leaks are not in the programmer's vocabulary. Anyhow, you probably won't run into this problem until later. If and when you do, just remember to deallocate all dynamic data that your pointers are pointing to BEFORE you alter the pointers.
__________________
-Aaron
 
 

Recent GIDBlogR for statistics by crystalattice

Thread Tools Search this Thread
Search this Thread:

Advanced Search
Rate This Thread
Rate This Thread:

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Forum Jump

Similar Threads
Thread Thread Starter Forum Replies Last Post
Tee chart problem Arun C++ Forum 0 01-Sep-2004 23:23
C I/O problem kelly80 C Programming Language 4 27-Apr-2004 20:15
Another FX 5600 problem (but with details that might shed light on this) BobDaDuck Computer Hardware Forum 2 16-Apr-2004 07:53
problem with php5 cgi installation fab13 Apache Web Server Forum 3 19-Nov-2003 09:11
unwanted scrollbar problem kelly001 Web Design Forum 3 24-Oct-2003 10:44

Network Sites: GIDNetwork · GIDWebHosts · GIDSearch · Learning Journal by J de Silva, The

All times are GMT -6. The time now is 18:44.


vBulletin, Copyright © 2000 - 2010, Jelsoft Enterprises Ltd.