PDA

View Full Version : overloading ++ --



mickey
3rd January 2008, 21:35
Hi, I overloading ++ and -- (postfix and prefix way) for my class Person with attributes _age, _name and _sex; but I have some problems and warning; ++ on Person must to increment the _age; both them incremet properly the objects Person.....


const Person& operator++() { //prefix //this seems me OK
_age++;
return *this;
}

const Person& operator++(int) { //postfix
Person before;
_age++;
return before;
}
warning person.h:37: warning: reference to local variable `before' returned


Is the second good (at the moment I'd like avoid "friend" member) ? Is a way to keep out that boring "warning", please?

jacek
3rd January 2008, 21:55
It isn't some "boring warning", it's a severe error. You return a reference to an object that went out of scope. operator++(int) should return Person, not const Person &.

mickey
3rd January 2008, 22:04
yes I see it; but why not const? It seem works fine with const too...

jacek
3rd January 2008, 22:08
yes I see it; but why not const? It seem works fine with const too...
The problem is in returning the reference not the const keyword.

mickey
3rd January 2008, 22:17
OK; about const, in this case it seems non influential its presence. Is it right?

jacek
3rd January 2008, 22:31
OK; about const, in this case it seems non influential its presence. Is it right?
Yes, it doesn't matter whether you return a const object or not.

mickey
4th January 2008, 01:49
hello,
speaking again about overloading I'm reading "thinking in c++" (online version) and at p507 "Return by value as const" I see when I have to use 'const' keys while overloading. In particular, I've noticed that when I do f(a+b) when f take a value and '+' is overloaded, there's no reason to do 'const' the returned value of operator+: this because the call of 'f' will do 'a+b' automatically 'const' (because a temporary object is a 'const'); probabily I lost something before in the book: what does mean the Bold ?

Thank you

Gopala Krishna
4th January 2008, 06:05
hello,
speaking again about overloading I'm reading "thinking in c++" (online version) and at p507 "Return by value as const" I see when I have to use 'const' keys while overloading. In particular, I've noticed that when I do f(a+b) when f take a value and '+' is overloaded, there's no reason to do 'const' the returned value of operator+: this because the call of 'f' will do 'a+b' automatically 'const' (because a temporary object is a 'const'); probabily I lost something before in the book: what does mean the Bold ?

Thank you

What Bruce says here is that,
A function is used usually as rvalue, that is its resultant is only used as read operation.
As such the parameter passed "a+b" will result in temporary object which will be an rvalue expression. Since rvalues are always constants, the temporary produced will therefore be const automatically regardless of whether you return const object or not.

However if you use "f( (a+b).someFunc() )" then, the value of "a+b" will be an lvalue if "a+b" returns "non const" object.
By returning const objects, you make sure the resultant of "a+b" is always an rvalue and hence non modifiable. In this case you can only call const functions of the object but not non const functions.

For eg

int a = 1, b = 2;
(a+b) = 4; // invalid because a+b for intergers returns a constant int and hence you cant modify it.

wysota
4th January 2008, 08:06
For me there is an easy rule - If you return a new object (a copy), there is no point in making the object const. When you return the same object (a reference), make it const if you want to forbid direct changes to the returned object (for example if you return a reference only because of overhead related to copying large objects). Otherwise return a non-const reference. There is also another aspect - returning const pointers for example if you want to forbid deleting the object by a 3rd party.

Investigating your case - postfix ++ returns a copy of the object before changes, so no const here. Prefix ++ returns a reference to the incremented object and the object is mutable, thus non const again. If you return a list or another complex structure and you want to force making a copy when the object is to be changed, return a const reference. In this case it is important to mark methods that don't change the object as const to prevent unnecessary copies:

struct X {
int func(){ return 7; }
int cFunc() const { return 7; }
const X &ref() { return *this; }
};

X x;
const X &x2 = x.ref();
x.func(); // success
x2.func(); // failure - modifying a const object
x2.cFunc(); // success
/* to call func() on x2 you need to make a copy: */
X x3 = x2; // copy
x3.func(); // success

mickey
4th January 2008, 16:54
I'm a little confused of how 'const' work; this below for me shouldn't work: cause 'const' keyword; but it seem works; why?


const Person& operator+=(const Person& right) {
//if (this == &right) {/* auto-assignment */ }
_age += right._age;
return *this;
}
//main.cpp
Person person1("markus"), Person2("Karl");
person1 += person2; //person1 isn't a const;

Could you me explain what 'const' make constant in this case, please?

jacek
4th January 2008, 17:42
const Person& operator+=(const Person& right)
[...]
person1 += person2; //person1 isn't a const;
The declaration says that operator += takes a const Person& as an argument and returns const Person &. It doesn't say that "this" object should be const.

You can pass non-const objects everywhere where const objects are allowed, because "const" means simply that you can't invoke methods that change the state of the object. It doesn't change the object in any way.


class SomeClass
{
...
int x() const { return x; }
void setX( int x ) { _x = x };
...
};
...
SomeClass obj;
const SomeClass & constRef = obj;

int x1 = obj.x(); // OK
int x2 = constRef.x(); // OK --- x() is marked as const (i.e. it doesn't change object's state)

obj.setX( 10 ); // OK
constRef.setX( 20 ); // ERROR
setX() might change the object, so we are not allowed to call, even if constRef is essentially the same thing as obj.

Also:
int x1 = constRef.x();
obj.setX( 999 );
int x2 = constRef.x(); // != x1
const doesn't say that object won't change --- it says that you can't change it.

The same applies to const objects.

mickey
4th January 2008, 18:10
hello,
refering to my post #10, could you show me any examples of operations (assigment or other) for which at first the returned value of operator+= has to be 'const' and at second, examples for which returned value of operator+= mustn't be 'const' ?
(my problem is 'const' on returned value....)
Thanks.

jacek
4th January 2008, 18:50
could you show me any examples of operations (assigment or other) for which at first the returned value of operator+= has to be 'const' and at second, examples for which returned value of operator+= mustn't be 'const' ?
There are no "must" or "musn't" in this case, but you don't gain anything if you return const reference instead of plain reference.

wysota
4th January 2008, 18:55
I can't think of any situation where the return value of operator+= would have to return a const object. You can do that of course but I just don't see a point.


X x;
x+=7; // OK
x = ++(x+=7); // invalid for const & operator+=
The last line would be invalid if operator+= returned a const object.