By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
455,515 Members | 1,848 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 455,515 IT Pros & Developers. It's quick & easy.

Question about Operator overloading

P: n/a
Hi,

I try to recall some C++ currently. Therefore I read the "Standard C++
Bible" by C. Walnum, A. Stevens and - of course there are chapters about
operator overloading.

Now I have a class xydata with operator- overloaded:

class xydata {
public:
xydata(double *x, double *y, int len)
...
xydata operator-(xydata subtr) {
int len = subtr.len();
double *xr = new double[len], *yr = new double[len];
// subract subtr from *this
...
xydata res(xr, yr, len);
return res;
}
}

For some reason, this results in a core dump, when I later do:
xydata a(...);
xydata b(...);
xydata c = a - b;
In contrast, when I return a pointer from the operator rather than an
object, everything works as expected:

class xydata {
public:
xydata(double *x, double *y, int len)
...
xydata* operator-(xydata subtr) {
int len = subtr.len();
double *xr = new double[len], *yr = new double[len];
// subract subtr from *this
...
xydata *res = new xydata(xr, yr, len);
return res;
}
}

// later
xydata a(...);
xydata b(...);
xydata *c = a - b;

In the book I mentioned above, I read that it should be possible to
return objects from overloaded operators. Did I miss something?

Thanks much in advance for a short clarification...
Eckhard
Nov 2 '05 #1
Share this Question
Share on Google+
7 Replies


P: n/a
Eckhard Lehmann wrote:
Hi,

I try to recall some C++ currently. Therefore I read the "Standard C++
Bible" by C. Walnum, A. Stevens and - of course there are chapters about
operator overloading.

Now I have a class xydata with operator- overloaded:

class xydata {
public:
xydata(double *x, double *y, int len)
...
xydata operator-(xydata subtr) {
xydata operator-(const xydata &subtr)

You don't want to copy subtr, nor do you want to modify it.
int len = subtr.len();
double *xr = new double[len], *yr = new double[len];
// subract subtr from *this
...
xydata res(xr, yr, len);
return res;
}
This should look like (semantically, of course):

X val1 = this->val1 - subtr.val1;
X val2 = this->val2 - subtr.val2;

return xydata(val1, val2);
}

For some reason, this results in a core dump, when I later do:
xydata a(...);
xydata b(...);
xydata c = a - b;
Looks to me that xydata doesn't have proper copy constructor and
destructor (and probably assignement operator). Without seeing the rest
of the class, just make sure xydata correctly copies and deletes the xr
and yr values you give it.
In contrast, when I return a pointer from the operator rather than an
object, everything works as expected:

class xydata {
public:
xydata(double *x, double *y, int len)
...
xydata* operator-(xydata subtr) {
Don't do that.
int len = subtr.len();
double *xr = new double[len], *yr = new double[len];
// subract subtr from *this
...
xydata *res = new xydata(xr, yr, len);
return res;
}
}

// later
xydata a(...);
xydata b(...);
xydata *c = a - b;
That's probably a memory leak, and it won't work as expected :

xydata a, b, c;
xydata *d = a - b - c; // error
In the book I mentioned above, I read that it should be possible to
return objects from overloaded operators. Did I miss something?


The problem is not with operator overloading, but with memory
management. Does

int main()
{
xydata a(..);
xydata b(a);
}

work correctly?
Jonathan

Nov 2 '05 #2

P: n/a
On Wed, 02 Nov 2005 19:10:20 +0100, Eckhard Lehmann <ec****@web.de>
wrote:
Hi,

I try to recall some C++ currently. Therefore I read the "Standard C++
Bible" by C. Walnum, A. Stevens and - of course there are chapters about
operator overloading.

Now I have a class xydata with operator- overloaded:

class xydata {
public:
xydata(double *x, double *y, int len)
...
xydata operator-(xydata subtr) {
int len = subtr.len();
double *xr = new double[len], *yr = new double[len];
// subract subtr from *this
...
xydata res(xr, yr, len);
return res;
}
}

For some reason, this results in a core dump, when I later do:
xydata a(...);
xydata b(...);
xydata c = a - b;
In contrast, when I return a pointer from the operator rather than an
object, everything works as expected:

class xydata {
public:
xydata(double *x, double *y, int len)
...
xydata* operator-(xydata subtr) {
int len = subtr.len();
double *xr = new double[len], *yr = new double[len];
// subract subtr from *this
...
xydata *res = new xydata(xr, yr, len);
return res;
}
}

// later
xydata a(...);
xydata b(...);
xydata *c = a - b;

In the book I mentioned above, I read that it should be possible to
return objects from overloaded operators. Did I miss something?


Usually one would implement operator-() not as a member function, but
as a non-member function and define it in terms of operator-=() which
would be a member function. The same goes for operator+(). Both the
non-member operator+() and operator-() would indeed return an object.

However, it seems that you have much more serious problems, namely
memory management ... you leak lots of memory because you call
operator new (and operator new[]) three times within the function, yet
there is no delete (nor delete[]) in sight???

Unfortunately, I don't know this book ... but if the sample code looks
anything like this, I would get a new book!

--
Bob Hairgrove
No**********@Home.com
Nov 2 '05 #3

P: n/a
Eckhard Lehmann wrote:
Hi,

I try to recall some C++ currently. Therefore I read the "Standard C++
Bible" by C. Walnum, A. Stevens and - of course there are chapters about
operator overloading.

Now I have a class xydata with operator- overloaded:

class xydata {
public:
xydata(double *x, double *y, int len)
...
xydata operator-(xydata subtr) {
Does your book really tell you to write an overloaded operator like that?
int len = subtr.len();
double *xr = new double[len], *yr = new double[len];
// subract subtr from *this
...
xydata res(xr, yr, len);
return res;
Why not

return xydata(xr, yr, len);
}
}

For some reason, this results in a core dump, when I later do:
xydata a(...);
xydata b(...);
xydata c = a - b;
In contrast, when I return a pointer from the operator rather than an
object, everything works as expected:

Probably the lack of a valid copy constructor.

class xydata {
public:
xydata(double *x, double *y, int len)
...
xydata* operator-(xydata subtr) {
int len = subtr.len();
double *xr = new double[len], *yr = new double[len];
// subract subtr from *this
...
xydata *res = new xydata(xr, yr, len);
return res;
}
}

// later
xydata a(...);
xydata b(...);
xydata *c = a - b;

In the book I mentioned above, I read that it should be possible to
return objects from overloaded operators. Did I miss something?
It's not just valid, it's the only sensible way to do it.

Thanks much in advance for a short clarification...

Does your class have a valid copy constructor, does it have a copy
constructor at all? Does you bible talk about copy constructors and
assignment operators and why they are important?

Here's a test, go back to the non-pointer version of your operator- but
this time remove the destructor from your class. If this time you don't
get a crash then the problem is the lack of a copy constructor.

Post again if your bible doesn't cover copy constructors.

Eckhard


john
Nov 2 '05 #4

P: n/a
lpw
"Eckhard Lehmann" <ec****@web.de> wrote in message
news:43***********************@news.freenet.de...
Hi,

I try to recall some C++ currently. Therefore I read the "Standard C++
Bible" by C. Walnum, A. Stevens and - of course there are chapters about
operator overloading.

Now I have a class xydata with operator- overloaded:

class xydata {
public:
xydata(double *x, double *y, int len)
...
xydata operator-(xydata subtr) {
int len = subtr.len();
double *xr = new double[len], *yr = new double[len];
// subract subtr from *this
...
xydata res(xr, yr, len);
return res;
}
}

For some reason, this results in a core dump, when I later do:
xydata a(...);
xydata b(...);
xydata c = a - b;
In contrast, when I return a pointer from the operator rather than an
object, everything works as expected:

class xydata {
public:
xydata(double *x, double *y, int len)
...
xydata* operator-(xydata subtr) {
int len = subtr.len();
double *xr = new double[len], *yr = new double[len];
// subract subtr from *this
...
xydata *res = new xydata(xr, yr, len);
return res;
}
}

// later
xydata a(...);
xydata b(...);
xydata *c = a - b;

In the book I mentioned above, I read that it should be possible to
return objects from overloaded operators. Did I miss something?

Thanks much in advance for a short clarification...
Eckhard

I would like to reitarate what others have said before: implement a good
copy contructor. Most importantly, make sure that your copy constructor
does a deep copy of the argument. Otherwise, since you seem to use
dynamically allocated members, deleting some object A will invalidate all
other objects from which A has been copied or for which A served as the
source copy. The same goes for the assignment operator, should you choose
to implement one as well.

Nov 2 '05 #5

P: n/a
> However, it seems that you have much more serious problems, namely
memory management ... you leak lots of memory because you call
operator new (and operator new[]) three times within the function, yet
there is no delete (nor delete[]) in sight???
I consider memory management - I just posted some code fragments that I
took for important to explain the problem.
Unfortunately, I don't know this book ... but if the sample code looks
anything like this, I would get a new book!


Nono.. this is a real world problem, not sample code ;-)!
The sample code in the book talks about a "Date" class and
"Employers/Persons", like computer books usually do. I haven't found
any errors in the sample code yet - at least not in the few passages
that I retyped.

Eckhard

Nov 3 '05 #6

P: n/a
> Does your book really tell you to write an overloaded operator like that?

No, but the book unfortunately gives only an example in which an int is
added to an object, not an object to another object. This is too simple
to cover all possibilities.
int len = subtr.len();
double *xr = new double[len], *yr = new double[len];
// subract subtr from *this
...
xydata res(xr, yr, len);
return res;
Why not

return xydata(xr, yr, len);


Between the construction of res and returning of res, the xr and yr
arrays are delete[]'d. I left that out here, because I didn't think
that it is important.
Does your class have a valid copy constructor, does it have a copy
constructor at all? Does you bible talk about copy constructors and
assignment operators and why they are important?


The book has a chapter on that, of course - I just didn't read it,
because I didn't think that it has something to do with operator
overloading.
Ok, after some reading and try & error - and the awesome and surprising
experience that it is obviously possible to access protected and
private members of a different object in an object method (??) - I have
a valid copy constructor:

xydata::xydata (const xydata& other)
{
this->_len = other._len; // _len is private - why can I acces it
here? strange

this->_data = new double[2 * this->_nPoints];
for (int i = 0; i < 2 * this->_nPoints; i++) {
this->_data[i] = other._data[i]; //the same here
}
}

Are objects of a class friends by default - or how can I explain this?
Anyway, thank you all for the help, I learned very much from this
diskussion..

Eckhard

Nov 3 '05 #7

P: n/a
ec****@web.de wrote:
Does your book really tell you to write an overloaded operator like that?

No, but the book unfortunately gives only an example in which an int is
added to an object, not an object to another object. This is too simple
to cover all possibilities.


The FAQ is quite good on this

http://www.parashift.com/c++-faq-lit....html#faq-13.9

Point 7 is the one that your code ignores (as do many other programmers).

int len = subtr.len();
double *xr = new double[len], *yr = new double[len];
// subract subtr from *this
...
xydata res(xr, yr, len);
return res;
Why not

return xydata(xr, yr, len);

Between the construction of res and returning of res, the xr and yr
arrays are delete[]'d. I left that out here, because I didn't think
that it is important.

Does your class have a valid copy constructor, does it have a copy
constructor at all? Does you bible talk about copy constructors and
assignment operators and why they are important?

The book has a chapter on that, of course - I just didn't read it,
because I didn't think that it has something to do with operator
overloading.
Ok, after some reading and try & error - and the awesome and surprising
experience that it is obviously possible to access protected and
private members of a different object in an object method (??) - I have
a valid copy constructor:

xydata::xydata (const xydata& other)
{
this->_len = other._len; // _len is private - why can I acces it
here? strange


It's perfectly logical when you understand the purpose of
public/private. It's to protect _code_ outside of the _class_ from
becoming dependent on the implementation details of the class. It's
nothing to with objects.

this->_data = new double[2 * this->_nPoints];
for (int i = 0; i < 2 * this->_nPoints; i++) {
this->_data[i] = other._data[i]; //the same here
}
}

Are objects of a class friends by default - or how can I explain this?


Friendship is something that is granted on a class by class basis, not
an object by object basis. So it makes no sense to say that objects of a
class are friends. But I get what you are saying, and yes it's true. If
this surprises you then you have misundetood the purpose of
public/private. Better look up the term 'encapsulation'.

john
Nov 3 '05 #8

This discussion thread is closed

Replies have been disabled for this discussion.