473,385 Members | 1,185 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,385 software developers and data experts.

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

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 student:public person
{
private:
string studentNo;
public:
student(string na, int ag, string sno):person(na, ag), studentNo(sno)
{}
void print(ostream &os) const
{
os << studentNo << " ";
person::print(os);
}
};

Apr 13 '06 #1
11 2128
<wf*****@libra.seed.net.tw> schrieb im Newsbeitrag news:11*********************@e56g2000cwe.googlegro 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
Apr 13 '06 #2
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?

Apr 13 '06 #3
<wf*****@libra.seed.net.tw> schrieb im Newsbeitrag news:11**********************@u72g2000cwu.googlegr 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
Apr 13 '06 #4
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


Apr 14 '06 #5
- person operator+(int n) const
- {
- return person(name, age+n);
- }

need to be changed into:

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

another way:
you can define friend function like
friend person operator+(person &p, int n);

Apr 14 '06 #6
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.

Apr 14 '06 #7
> 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.

Apr 14 '06 #8
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);
}
};

Apr 14 '06 #9
wf*****@libra.seed.net.tw 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
Apr 14 '06 #10
Tom
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):person(na, ag),
studentNo(sno)
{}

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

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

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

Apr 17 '06 #11
wf*****@libra.seed.net.tw 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:
What you want to do equal to the assignment " person2 = person1 +
age_addition", right ?

So you need (1) default constructor (2) copy constructor (3) friend
function for operatotr +
virtual person operator+(int n) const
{
return person(name, age+n);


person(name, age+n) is live only in the scope of the function inside,
the local object will be deleted when out of the scope. In order to
keep the local object life, you can define it as a static object;

==================================
FYI, you can test the following code:
==================================
#include <iostream>
#include <string>
using namespace std;

class person
{
protected:
string name;
int age;

public:

person() :name(""), age(0){}

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

person(const person& p);

friend person& operator+(const person&, int n);

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

};

person::person(const person& p)
{
name = p.name;
age = p.age;
}

person& operator+ (const person &p, int n)
{
static person default_person;
default_person.name = p.name;
default_person.age = p.age + n;
return default_person;
}

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

}

int main()
{
person p("student", 20);
cout << p << endl;
cout << p + 5 << endl;
cout << p << endl;
return 0;
}

Apr 17 '06 #12

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

6
by: Victor | last post by:
Anyone knows how to write a virtual function for operator<< ? I have a base class and some public derived class from it. For the derived class, I hope they can use << to output their different...
16
by: gorda | last post by:
Hello, I am playing around with operator overloading and inheritence, specifically overloading the + operator in the base class and its derived class. The structure is simple: the base class...
2
by: Steffen | last post by:
Hi, is there a simple way to use operators overloaded in some class for objects of a derived class? In my example I have a class Matrix that represents 2x2 matrices, and I overloaded...
23
by: Randy | last post by:
Since these operators can't be member functions, and since friend functions can't be declared virtual, how do I make my inserters and extractors polymorphic? --Randy Yates
2
by: allan.mcrae | last post by:
I am having trouble with overloading the += operator when template parameters are used. I have a class holding an array (called "derived" in the following example) which derives from a base class...
6
by: Bill foust | last post by:
I'm running into a situation there I think an operator overload would solve the issue, but I'm unable to make it work for some reason. If anyone can help here I would appreciate it. I have a...
5
by: noone | last post by:
hi. I don't use exceptions much in the embedded world, but for my plugin interface to a hardware MPEG encoder I'd like to, since there are so many places that the crummy kernel driver can do bad...
11
by: Zilla | last post by:
I have the following simple program. I just want to be able to do math operations (+, -, =)on Timer sublcasses, but want to handle cases where either rhs or lhs is an intrinsic value, However, the...
14
by: Hunk | last post by:
Hi I ws wondering if there is a way to implement operator+ in case of virtual classes. Here's the problem. I have to have a base string class from which two classes (normal char string and a...
6
by: Rob McDonald | last post by:
I would like to force all the classes in my hierarchy to implement the << operator for testing purposes. My base class is a pure virtual class. I started out by working with operator...
1
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...
0
by: ryjfgjl | last post by:
In our work, we often need to import Excel data into databases (such as MySQL, SQL Server, Oracle) for data analysis and processing. Usually, we use database tools like Navicat or the Excel import...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.