Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > operator overloading in the derived class could not work...

Reply
Thread Tools

operator overloading in the derived class could not work...

 
 
wfhsiao@libra.seed.net.tw
Guest
Posts: n/a
 
      04-13-2006
Hello,

while refreshing my understanding of C++, I found the overloaded
operators could not work properly. Why my following codes keep printing
the student b's data as a person's? Did I lost anything? Thanks for
your help!

person a("John", 30);
student b("Mary", 20, "93406001");
person *p[2] = {&a, &b};
for (int j=0; j<2; j++)
cout << (*p[j]+3) << endl;

The definitions of person and student are listed below.
--------------------------------
class person
{
private:
string name;
int age;
public:
person(string na, int ag):name(na), age(ag) {}
person operator+(int n) const
{
return person(name, age+n);
}
virtual void print(ostream& os) const
{
os << name << " " << age;
}
};

ostream& operator<< (ostream& os, const person &aP)
{
aP.print(os);
return os;
}
-----------------------------------
class studentublic person
{
private:
string studentNo;
public:
student(string na, int ag, string sno)erson(na, ag), studentNo(sno)
{}
void print(ostream &os) const
{
os << studentNo << " ";
person:rint(os);
}
};

 
Reply With Quote
 
 
 
 
Heinz Ozwirk
Guest
Posts: n/a
 
      04-13-2006
<(E-Mail Removed)> schrieb im Newsbeitrag news:(E-Mail Removed) ups.com...
> Hello,
>
> while refreshing my understanding of C++, I found the overloaded
> operators could not work properly. Why my following codes keep printing
> the student b's data as a person's? Did I lost anything? Thanks for
> your help!
>
> person a("John", 30);
> student b("Mary", 20, "93406001");
> person *p[2] = {&a, &b};
> for (int j=0; j<2; j++)
> cout << (*p[j]+3) << endl;

....

What does the program print and what do you expect?

Heinz
 
Reply With Quote
 
 
 
 
wfhsiao@libra.seed.net.tw
Guest
Posts: n/a
 
      04-13-2006
Obviously I would like to see the corresponding print function be
issued. Since p[0] refers to a person object, while p[1], a student
object. The result should reasonably be as follows:
John 33
93406001 Mary 23

However, it is quite frustrated. The result it printed out is
John 33
Mary 23

So my question is how to make "the operator+" work as what I want?

 
Reply With Quote
 
Heinz Ozwirk
Guest
Posts: n/a
 
      04-13-2006
<(E-Mail Removed)> schrieb im Newsbeitrag news:(E-Mail Removed) oups.com...
> Obviously I would like to see the corresponding print function be
> issued. Since p[0] refers to a person object, while p[1], a student
> object. The result should reasonably be as follows:
> John 33
> 93406001 Mary 23
>
> However, it is quite frustrated. The result it printed out is
> John 33
> Mary 23
>
> So my question is how to make "the operator+" work as what I want?


[Code from original post]
> person a("John", 30);
> student b("Mary", 20, "93406001");
> person *p[2] = {&a, &b};
> for (int j=0; j<2; j++)
> cout << (*p[j]+3) << endl;
>
> The definitions of person and student are listed below.
> --------------------------------
> class person
> {
> private:
> string name;
> int age;
> public:
> person(string na, int ag):name(na), age(ag) {}
> person operator+(int n) const
> {
> return person(name, age+n);
> }


operator+ creates a new object of type person. It doesn't matter that the object for which it has been called is of a derived type. Your code tells the compiler to return a person, not a student, so you get what you asked for. If you want operator+ to behave differently for objects of type student, you have to implement it for class student, too. Without it the compiler does not lnow how to add an int to a student. It only knows that students are persons, too, and how to add an int to a person, and it knows that the result of such an operation is a person, but not a student. Actually, when compiling class person, it doesn't even know that there is such a thing as a student.

HTH
Heinz
 
Reply With Quote
 
wfhsiao@libra.seed.net.tw
Guest
Posts: n/a
 
      04-14-2006
Yes. This is a reasonable conjecture, and I tried it before but in
vain. (Sorry for not providing all these information at the very
beginning, 'cause I thought you might ever encounter and solve such
questions.)

I added the following code to the student class, and modified the
access modifier of name and age in person from private to protected,
accordingly.
student operator+(int n) const
{
return student(name, age+n, studentNo);
}

The printed result is still the same.
> John 33
> Mary 23


 
Reply With Quote
 
wfhsiao@libra.seed.net.tw
Guest
Posts: n/a
 
      04-14-2006
Thanks! Your first method can work. However, it has the drawback of
side-effect: the object's content has been modified. Is there any other
way? The second method, using friend, could not work, even when I
define such a friend function for student class.

 
Reply With Quote
 
dan2online
Guest
Posts: n/a
 
      04-14-2006
> The second method, using friend, could not work, even when I
> define such a friend function for student class.


You need a copy constructor. Try it.

 
Reply With Quote
 
wfhsiao@libra.seed.net.tw
Guest
Posts: n/a
 
      04-14-2006
Nope, I have tried it, but it still did not work. (Here to work means
it can successfully print out the student object's data; the proposed
friend function can only print out person's data). Should I declare the
operator+ as a virtual function as below? But obviously it won't work
since the derived class could not overwrite it, since their return
types are different. Could someone give me more hints?

class person
{
public:
virtual person operator+(int n) const
{
return person(name, age+n);
}
};

class student: public person
{
public:
virtual student operator+(int n) const
{
return student(name, age+n, studentNo);
}
};

 
Reply With Quote
 
Victor Bazarov
Guest
Posts: n/a
 
      04-14-2006
http://www.velocityreviews.com/forums/(E-Mail Removed) wrote:
> Nope, I have tried it, but it still did not work. (Here to work means
> it can successfully print out the student object's data; the proposed
> friend function can only print out person's data). Should I declare
> the operator+ as a virtual function as below? But obviously it won't
> work since the derived class could not overwrite it, since their
> return types are different. Could someone give me more hints?
>
> class person
> {
> public:
> virtual person operator+(int n) const
> {
> return person(name, age+n);
> }
> };
>
> class student: public person
> {
> public:
> virtual student operator+(int n) const
> {
> return student(name, age+n, studentNo);
> }
> };


That wouldn't compile. The return value has to be covariant.

I think 'dan2online's suggestion about making your operator + return
a reference has merit.

The main question here is, why do you want to have it as an operator?
Couldn't you use a normal (named) function? The problem, of course,
is that you cannot follow both the recommendation that operator + must
return an object and that virtual functions need to have covariant
returns, _without_ creating some kind of proxy object and building
other things around it. If you just allow your operator+ return
a reference to 'person', your problems should go away.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask


 
Reply With Quote
 
Tom
Guest
Posts: n/a
 
      04-17-2006
Actually, I tried some other solutions, and I guess using += and
clone() might be the best way to avoid this problem.
//---------------------------------------------------------------------------------------
class person
{
protected:
string name;
int age;

public:
person(string na, int ag):name(na), age(ag) {}

virtual person* clone() const
{
return (new person(name, age));
}

virtual person& operator += (int n)
{
age += n;
return *this;
}

virtual void print(ostream& os) const
{
os << name << " " << age;
}
};

ostream& operator<< (ostream& os, const person &aP)
{
aP.print(os);
return os;
}

class student : public person
{
string studentNo;

public:
student(string na, int ag, string sno)erson(na, ag),
studentNo(sno)
{}

virtual person* clone() const
{
return (new student(name, age, studentNo));
}

void print(ostream &os) const
{
os << studentNo << " ";
person:rint(os);
}
};

int main()
{
student s("student", 20, "1000");
std::auto_ptr<person> sp(s.clone());
std::cout << (*sp += 3) << std::endl;
}

 
Reply With Quote
 
 
 
Reply

Thread Tools

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

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Derived Structure in Derived Class?? David C++ 3 01-29-2008 07:38 AM
Derived::Derived(const Base&) and Derived& operator=(const Base&) developereo@hotmail.com C++ 1 05-23-2007 01:44 PM
Derived::Derived(const Base&) and Derived& operator=(const Base&) developereo@hotmail.com C++ 1 05-23-2007 12:07 AM
operator-overloading of nested class inside a template class Gerhard Pfeiffer C++ 3 09-14-2006 06:46 PM
Accessing inherited operator<< in base class from derived class Alicia C++ 3 11-24-2004 03:35 AM



Advertisments