views:

241

answers:

4

Hi! I'm a little confused as to why I've been told to return const foo from a binary operator in c++ instead of just foo.

I've been reading Bruce Eckel's "Thinking in C++", and in the chapter on operator overloading, he says that "by making the return value [of an over-loading binary operator] const, you state that only a const member function can be called for that return value. This is const-correct, because it prevents you from storing potentially valuable information in an object that will be most likely be lost".

However, if I have a plus operator that returns const, and a prefix increment operator, this code is invalid:

class Integer{
int i;

public:
    Integer(int ii): i(ii){ }
    Integer(Integer&);

    const Integer operator+();
    Integer operator++();
};


int main(){

Integer a(0);
Integer b(1);

Integer c( ++(a + b));
}

To allow this sort of assignment, wouldn't it make sense to have the + operator return a non-const value? This could be done by adding const_casts, but that gets pretty bulky, doesn't it?

Thanks!

A: 

Copy constructors usually take a const reference, solving that problem for you.

(Having non-const copy ctor implies some transfer of resources, which can be useful sometimes, but for 99% of all situations, it's not needed)

Marcus Lindblom
+5  A: 

When you say ++x, you're saying "add 1 to x, store the result back into x, and tell me what it was". This is the preincrement operator. But, in ++(a+b), how are you supposed to "store the result back into a+b"?

Certainly you could store the result back into the temporary which is presently holding the result of a+b, which would vanish soon enough. But if you didn't really care where the result was stored, why did you increment it instead of just adding one?

Managu
+3  A: 

FYI, ++(a + b) is illegal even with PODs (plain old data types, like int). So it makes sense not to allow it for your own class types either. Try this:

int a = 1;
int b = 2;
int c = ++(a+b);

GCC returns error: lvalue required as increment operand.

In your case, it would be preferable make your copy constructor take a const Integer argument, and create your Integer c like this instead:

Integer c(a + b + Integer(1));
int3
A: 

Having the + operator return a const value is usually a good idea as it can also prevent unintended assignments.

if( ( a + b ) = 0 );

It would seems that this person is trying to test if a + b is equal to 0 but used = instead of ==. Having the + operator return a const value will result in this line throwing an error.

Here is your class again with a working + operator and copy constructor:

class Integer
{
    int i;
public:

    Integer(int ii): i(ii){}
    Integer( const Integer& p): i( p.i ){}

    const Integer operator+(  const Integer& a ){ return a.i + i; } const;

    Integer operator++(){ ++i; return *this; };
};

Now if you still want to increment the returned value of + you should do this:

Integer c( ++Integer( a + b ) );

That will use the const object returned to create a new temporary variable, increment it, and then use it to construct c;

HTH.

0xC0DEFACE