assignment operator question

M

Matthew Polder

Hi,

When a class Apple is written and the assignment operator is not
explicitly declared, the operator

Apple& operator=(const Apple&)

is created by the compiler. Is there any difference between this and

const Apple& operator=(const Apple&)

other than the second form means that you can't do this:

Apple a, b, c;
//Assume there is a function 'Apple operator+(const Apple&, const
Apple&)'

(a + b) = c; //not allowed with second assignment operator, I think.


thanks,
matthew
--



Please remove the word 'tuna' from my name and add a dot j dot ('.j.')
for my correct email address. If you are a spammer please add the word
"Istink" after the word tuna.
 
S

Sharad Kala

Matthew Polder said:
Hi,

When a class Apple is written and the assignment operator is not
explicitly declared, the operator

Apple& operator=(const Apple&)

is created by the compiler. Is there any difference between this and

const Apple& operator=(const Apple&)

other than the second form means that you can't do this:

Apple a, b, c;
//Assume there is a function 'Apple operator+(const Apple&, const
Apple&)'

Assignment operator groups right to left.
a=b=c=d, i would expect a and d to have same values. Was it possible if return
type was const Apple& ?
 
J

John Harrison

Matthew Polder said:
Hi,

When a class Apple is written and the assignment operator is not
explicitly declared, the operator

Apple& operator=(const Apple&)

is created by the compiler. Is there any difference between this and

const Apple& operator=(const Apple&)

other than the second form means that you can't do this:

Apple a, b, c;
//Assume there is a function 'Apple operator+(const Apple&, const
Apple&)'

(a + b) = c; //not allowed with second assignment operator, I think.

No this would be allowed by either form of the assignment operator, assuming
a valid declaration of operator+.

The difference is this

(a = b) = c

With the second form (a = b) returns a const reference which cannot then go
on the left hand side of another operator= (because operator= is not a const
method).

(a = b) = c is pretty useless for built in types like int, but it is legal,
so why not make the same thing legal for user defined classes as well?

john
 
S

Sharad Kala

Sharad Kala said:
a=b=c=d, i would expect a and d to have same values. Was it possible if return
type was const Apple& ?

Sorry, actually it should be ((a=b)=c)=d.
 
J

JKop

Matthew Polder posted:
Hi,

When a class Apple is written and the assignment operator is not
explicitly declared, the operator

Apple& operator=(const Apple&)

is created by the compiler. Is there any difference between this and

const Apple& operator=(const Apple&)

other than the second form means that you can't do this:

Apple a, b, c;
//Assume there is a function 'Apple operator+(const Apple&, const
Apple&)'

(a + b) = c; //not allowed with second assignment operator, I think.


thanks,
matthew


Think about that for a second. If it returned a const reference, ie. the
object itself is const, then you wouldn't be allowed use the assignment
operator in the first place!


-JKop
 
R

Rob Williscroft

JKop wrote in in comp.lang.c++:

Matthew Polder posted:
Think about that for a second. If it returned a const reference, ie. the
object itself is const, then you wouldn't be allowed use the assignment
operator in the first place!

You (and possibly the OP) appear to be confusing a member function
returning a reference to const and a member function that is const.

struct X
{
X const &a() { return *this; }
X &b() const
{
static X x;
return x;
}
};

Above a() can be called only on non-const X's, b() can be
called on both.

Its very common that const member functions return constants
and that non-const member functions return non-constants.

But it isn't required.

Rob.
 
D

David Harmon

On Fri, 18 Jun 2004 19:28:52 +0530 in comp.lang.c++, "Sharad Kala"
Sorry, actually it should be ((a=b)=c)=d.

That is a bad thing to write; many readers will fail to understand it,
making your code expensive to maintain. If that sequence is your intent
then write it as three statements:
a=b;
a=c;
a=d;
 
D

David Harmon

Think about that for a second. If it returned a const reference, ie. the
object itself is const, then you wouldn't be allowed use the assignment
operator in the first place!

Eh? Forming a const reference to an object doesn't suddenly make the
object const. Most of the time the return type is not all that
important, since the return value of operator= is often unused.
 
S

Sharad Kala

David Harmon said:
On Fri, 18 Jun 2004 19:28:52 +0530 in comp.lang.c++, "Sharad Kala"


That is a bad thing to write; many readers will fail to understand it,

Ofcourse, I am not recommending someone to write such a thing.
 
J

Jack Klein

No this would be allowed by either form of the assignment operator, assuming
a valid declaration of operator+.

The difference is this

(a = b) = c

With the second form (a = b) returns a const reference which cannot then go
on the left hand side of another operator= (because operator= is not a const
method).

(a = b) = c is pretty useless for built in types like int, but it is legal,
so why not make the same thing legal for user defined classes as well?

john

Given:

int a, b = 2, c = 3;

....then:

(a = b) = c;

....is syntactically legal in C++ (not in C), but perhaps it should not
be. Since the statement modifies the value of a twice without an
intervening sequence point, it produces undefined behavior.

I understand the purpose of changing the return type of the assignment
operators from rvalue (as they are in C) to lvalue, for use with user
defined types. There the assignment operator has the semantics of a
function, and there are sequence points.

There is no way to use the fact that assignment to a built-int
evaluates to an lvalue result other than using the & operator on it
without invoking undefined behavior. You can do this in C++, but not
in C:

#include <iostream>

void func(int *q)
{
++*q;
}

int main()
{
int x;
func(x = 3);
std::cout << "x = " x "\n";
return 0;
}

....and the output will be 4.

In fact this leads to the mess in C++ with volatile values. Given:

volatile int x;
int y; /* not volatile */

y = x = 3; /* equivalent to y = (x = 3) */

The first assignment, 'x = 3' produces not the integer value 3, but
the address of x. The C++ standard requires the compiler perform
lvalue to rvalue conversion, and it most certainly cannot optimize it
away with x being volatile.

In fact, it is at least arguable that:

x = 3;

....requires lvalue to rvalue conversion (reading x after writing),
because even though the rvalue is not used, the semantics of the
volatile type qualifier require it.

And think of memory-mapped hardware devices (the sort of thing one
uses volatile for) like UARTs where the transmit register is
write-only, the receive register is read-only, and they both occupy
the same address...
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top