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 02-Nov-2009, 22:28
Howard_L Howard_L is offline
Regular Member
 
Join Date: Apr 2007
Location: Maryland/PA, USA
Posts: 802
Howard_L is a jewel in the roughHoward_L is a jewel in the roughHoward_L is a jewel in the rough

Overloaded operator + base / derived class question


Hi, I have been learning about inheritance and then began to try some overloaded operators in them.
It was all making sense until I ran into something which I try to condense into the program below.
In there you will see I have two "myteries" which I could use some help in understanding.
CPP / C++ / C Code:
#include <iostream>
using namespace std;

class BASE
{
  public:
    int x, y;
    BASE() {x = 0; y = 0; }
    BASE(int a, int b) { x = a; y = b; }
    BASE operator + (BASE param)
    {
      BASE temp;
      temp.x = x + param.x;
      temp.y = y + param.y;
      cout << "OLOP1 \n";
      return (temp);
    }
};

class DERIVED : public BASE
{
  public:
    int z;
    DERIVED() { z = 0; }
    DERIVED(int a, int b, int c) { x= a; y= b; z= c; }

    DERIVED operator + (DERIVED param)
    {
      DERIVED temp;
      temp.x = x + param.x;
      temp.y = y + param.y;
      temp.z = z + param.z;
      cout << "OLOP2 \n";
      return temp;
    }

    DERIVED operator + (BASE param)  // see if I can do this Yes!
    {
      DERIVED temp;
      temp.x = x + param.x;
      temp.y = y + param.y;
      temp.z = z;
      cout << "OLOP3 \n";
      return temp;
    }

    /**** mystery1:  The compiler won't allow this for some reason:
  
    BASE operator + (BASE param)
    {
      BASE temp;
      temp.x = x + param.x;
      temp.y = y + param.y;
      return temp;
    }
    // :49: error: ‘BASE DERIVED::operator+(BASE)’ cannot be overloaded
    // :37: error: with ‘DERIVED DERIVED::operator+(BASE)’
    ****/
};

int main()
{
  BASE b1(3, 4) , b2;
  DERIVED d1( 7, 8, 9) , d2;

  cout << "\nb1.x= " << b1.x << "  b1.y= " << b1.y << "    "
       <<   "b2.x= " << b2.x << "  b2.y= " << b2.y << "\n";

  cout << "d1.x= " << d1.x << "  d1.y= " << d1.y << "  d1.z= " << d1.z << "    "
       << "d2.x= " << d2.x << "  d2.y= " << d2.y << "  d2.z= " << d2.z <<"\n\n";

  // OLOP2 works ok:
  d2 = d1 + d1;
  cout << "d2 = d1 + d1  :  d2.x= " << d2.x << "  d2.y= " << d2.y << "  d2.z= " << d2.z <<"\n\n";

  // OLOP3 works ok
  d2 = d1 + b1;
  cout << "d2 = d1 + b1  :  d2.x= " << d2.x << ",  d2.y= " << d2.y << "  d2.z= " << d2.z <<"\n\n";

  // mystery2 but it allows me to do the operation below:
  cout << "First print existing values: \n" <<
          "d1.x= " << d1.x << ",  d1.y= " << d1.y << ", d1.z=" << d1.z
       << "    b1.x= " << b1.x << ",  b1.y= " << b1.y
       << "\nNow see how this gets done by olop3: \n \n";

  b2 = d1 + b1;
  cout << "b2 = d1 + b1 : b2.x= " << b2.x << ",  b2.y= " << b2.y << "\n";

  cout << "\nHow can that work when the compiler won't even allow me to \ndefine a specific operator for it? \n\n";

  return 0;
}
The output for that is:
Code:
overloaded> g++ -Wall -W -pedantic olop-2.cpp -o olop-2 overloaded> ./olop-2 b1.x= 3 b1.y= 4 b2.x= 0 b2.y= 0 d1.x= 7 d1.y= 8 d1.z= 9 d2.x= 0 d2.y= 0 d2.z= 0 OLOP2 d2 = d1 + d1 : d2.x= 14 d2.y= 16 d2.z= 18 OLOP3 d2 = d1 + b1 : d2.x= 10, d2.y= 12 d2.z= 9 First print existing values: d1.x= 7, d1.y= 8, d1.z=9 b1.x= 3, b1.y= 4 Now see how this gets done by olop3: OLOP3 b2 = d1 + b1 : b2.x= 10, b2.y= 12 How can that work when the compiler won't even allow me to define a specific operator for it? overloaded>
So you see, the olop3 seems to work ok and not cause harm but it just doesn't seem right. Looks like it could be hazardous!
Any light ya'll could shed on those mysteries would be apprecianado.
Thanks , Howard
  #2  
Old 03-Nov-2009, 07:17
Kimmo Kimmo is offline
Member
 
Join Date: Mar 2007
Location: Finland
Posts: 285
Kimmo is a jewel in the roughKimmo is a jewel in the roughKimmo is a jewel in the rough

Re: overloaded operator + base / derived class question


CPP / C++ / C Code:
    /**** mystery1:  The compiler won't allow this for some reason:
  
    BASE operator + (BASE param)
    {
      BASE temp;
      temp.x = x + param.x;
      temp.y = y + param.y;
      return temp;
    }
    // :49: error: ‘BASE DERIVED::operator+(BASE)’ cannot be overloaded
    // :37: error: with ‘DERIVED DERIVED::operator+(BASE)’
    ****/
Overloaded functions may differ only by their argument lists, not by their return types. (And why would you want to define such a method in the subclass anyway? ... Especially when you already have the exact same method in the base class?)


CPP / C++ / C Code:
  b2 = d1 + b1;
You have an
CPP / C++ / C Code:
DERIVED operator + (BASE param)
defined, so this matches the call DERIVED + BASE. As for the assignment, it works because a derived class is always also a base class. The additional derived class information is just 'sliced' away and this way a base class object is assigned to the variable.

Google "c++ slicing" or similar to find discussions. I don't know exactly in what cases this is a bad thing as long as you keep in mind for example the following:
CPP / C++ / C Code:
std::vector<BASE> BASEVector;
BASEVector.push_back(b1);  // add a BASE class object
BASEVector.push_back(d1);  // also add a BASE class object

It's also good habit to pass by reference in these cases, like this:
CPP / C++ / C Code:
DERIVED operator+(const DERIVED& param);
  #3  
Old 03-Nov-2009, 08:33
Howard_L Howard_L is offline
Regular Member
 
Join Date: Apr 2007
Location: Maryland/PA, USA
Posts: 802
Howard_L is a jewel in the roughHoward_L is a jewel in the roughHoward_L is a jewel in the rough

Re: overloaded operator + base / derived class question


Nice explainations, thanks.
Quote:
Overloaded functions may differ only by their argument lists, not by their return types...
...Especially when you already have the exact same method in the base class?
I see. Hmm , about that method in the base class. When I was getting the "BASE DERIVED:perator+(BASE)’ cannot be overloaded" error I was suprised that I got no error refering to the line:
CPP / C++ / C Code:
b2 = d1 + b1;
I was even more suprised that it ran and the output looked correct.
At first I thought it might be that OLOP1 was being used and I put those little couts in each one to find out.
Then I was suprised to see that it was OLOP3 that was being used.
You explained how that is possible , but now I am curious why OLOP1 was not used?
( And then how it could be used at all from the derived class? )
But don't worry about it, I understand enough for now. I'll just keep rolling and gather some more moss.
Thanks again, Howard
  #4  
Old 05-Nov-2009, 10:19
Kimmo Kimmo is offline
Member
 
Join Date: Mar 2007
Location: Finland
Posts: 285
Kimmo is a jewel in the roughKimmo is a jewel in the roughKimmo is a jewel in the rough

Re: overloaded operator + base / derived class question


Quote:
Originally Posted by Howard_L
You explained how that is possible , but now I am curious why OLOP1 was not used?
( And then how it could be used at all from the derived class? )
You could call the base class implementation first like this
CPP / C++ / C Code:
DERIVED operator + (DERIVED param)
    {
      DERIVED temp(BASE::operator+(param));
//      temp.x = x + param.x;
//      temp.y = y + param.y;
      temp.z = z + param.z;
      cout << "OLOP2 \n";
      return temp;
    }
However, there's probably something I don't quite remember here, because it seems you also need to provide a constructor taking a BASE argument, for example:
CPP / C++ / C Code:
DERIVED(BASE base) : BASE(base), z(0) {}
This makes sense, but I'd think there is an easier way too...


If anyone knows how it's "done right", please share.
 
 

Recent GIDBlogProgramming ebook direct download available 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
How to get a handle to a derived class? Futterama MS Visual C++ / MFC Forum 1 29-Jan-2007 10:47
Hard drive/CPU Diagnoses Issues binarybug Computer Hardware Forum 1 22-Jan-2007 20:23
Message Class TransformedBG C++ Forum 5 29-Nov-2006 22:28
a tester class and then some. postage Java Forum 1 06-May-2006 16:48
Opinion on my code and a c++ class question FlipNode C++ Forum 7 07-Feb-2006 09:15

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

All times are GMT -6. The time now is 15:47.


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