Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Chris Miller on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

assignment operator overloading

Status
Not open for further replies.

bkelly13

Programmer
Aug 31, 2006
98
US
Windows 7, Visual Studio 2008 C++

Assignment operator overload
Horton's book VS C++ 2008 provides this example of operator overloading for classes:
Code:
motto1 = motto2 = motto3;
where motto1 through3 are instances of class CMessage and contain member function of type char * for an example. Then he presents the following line of code that should work properly:
Code:
(motto_1 = motto2) = motto3;
This makes no sense to me. I understand that for integers:
Code:
 x = y = 3
will result in y being set to 3 then x being set to y. But the parenthized version makes no sense. I wrote it up and ran it as:
Code:
int x = 1; int y = 3; int z = 7;
(x = y ) = z;
x wound up with 7, while y and z were unchanged. The debugger would not step into that line of code so I cannot state what happend with certainty. But, it appears that x gets the value of y, then x gets the value of z.

And the question is: Horton probably had a reason for putting this in the text. What might that reason be?

We need to know what a dragon is
before we study its anatomy.
(Bryan Kelly, 2010)
 
Standard assignment operator returns a reference to the left side. Execution order of (x = y) = z:
Code:
1. x = y, returns reference to x
2. (reference to x) = z, i.e. x = 7 in your case
Be careful: redefined assignment operators may return other types!
 
When the compiler emits code for
Code:
int a,b;
a = b;

I am pretty sure it does not provide a referernce to a or b than can be used for anything. If instead a and b are classes or structures, why would anyone need the equal operator to return a reference. Does that mean that we can write code such as:
Code:
Class C_Z{...}

C_Z*  a  = new( C_Z);
C_Z*  b  = new( C_Z);

C_Z* c = NULL;

c = (a = b);

I am open to syntax corrections but please don't let that disrupt the question. The goal is to illustrate the creation of two classes, use an overloaded equal operator, create a pointer to the same class, then save that returned reference.

And if that is valid, would c have the same address as a or as b. It would not have its own address as there was never a c instantiated.




We need to know what a dragon is
before we study its anatomy.
(Bryan Kelly, 2010)
 
c = (a = b);

is valid. All pointers would take the address that b points to and you'd get a memory leak in whatever a used to point to. The = operator returns a reference to whatever is on the left.

If you had
Code:
int x = 10, y = 20;

(x = y) += 10;
std::cout << x << y << std::endl;
[/cout]
You'd get 30 and 20.
 
Please, don't mix up assignment operator =(...) and equal operator ==(...).

In your snippet
Code:
int a, b;
a = b;
"a = b" is an EXPRESSION and its result value is a reference to a. Of course, this expression has size effect: value assignment.

But "a=b;" is an expression STATEMENT in C++ (in C too). An expression statement discards the value of its expression. That's why the compiler does not emit any codes for "a=b" expression result of an expression statement.

Can you explain what's your OP question? Yes, "(x=y) = z" expression is not an example of a good style. Moreover, if z, y and z are integers the language does not define what's the value of x after this expression evaluation (undefined order of side effects)!

May be you want to understand why did we add assignment operator(s) to our classes? It's the other story.

By the way, redefined operator =(...) is not obliged to implement an assignment of whatever to the class object...
 
ArkM wrote
In your snippet
Code:
int a, b;a = b;"a = b"
is an EXPRESSION and its result value is a reference to a. Of course, this expression has size effect: value assignment.

I am not able to track that at all. Variable a may reside at location 1000 and contain 1, b at 1004 and contain 2. The code a = b; means that location 1000 now contains 2. So where is this reference? What code can I write to get that reference from the code statement a = b;

BTW: I have always disliked the term "reference." Its an address so why not call it an address?

We need to know what a dragon is
before we study its anatomy.
(Bryan Kelly, 2010)
 
We are on the C++ language forum. The term "reference" is a part of C++ language definition. So it's not a matter of taste.

C++ references are not vulgar "memory addresses". In C++ and C "address" analogue is a pointer.

An assignment is not a statement in C and C++. It's a binary operator (has two operands). See, for example:
Code:
func(&(a=b));
 
Hello ArkM,
Let me back up a bit and rephrase. And that rephrase statement may provide a clue to my errors.
Start with two instantiations of a class, A and B. Presume that operator overload has been defined for = such that all pointers and such are properly copied. From what I have read, if we write:
Code:
 a = b;
The operator returns a reference. Where is this reference? How do I get access to it and why might I need it.



We need to know what a dragon is
before we study its anatomy.
(Bryan Kelly, 2010)
 
Hello bkelly13

Let's consider another expression: os >> i where os type is std::istream and

i's type is int. It returns a reference to os (by the language standard

library definition). Where is this reference?

It depends on this expression context.
#1:
Code:
os >> i;
We place the expression to an expression statement context (see semicolon).

No need in this expression value.
#2:
Code:
if (os >> i)
We are in the context where the language expects bool value. There is a chain

of conversions from a reference to std::istream to bool. That's ok, we can

test the input result.
#3:
Code:
os >> i >> j;
Binary operator >> is left associative so this expression evaluation order

looks like:
Code:
((os>>i)>>j)
The 1st subexpression yields reference to os - so the second operator has a

proper left argument type (std::istream&, i.e. reference to std::istream).

Let's come back to operator =():
Code:
x = y = 1;
This operator is right associative so the expression evaluation order is:
Code:
(x=(y=1))
The last subexpression yields the reference to y, so this double assignment is the same as y = 1 then x = y. It's not y = 1 then x = 1. Feel the difference (especially for user defined assignments).
Now about pathetic question:
Code:
a = b;
>Where is this reference? How do I get access to it and why might I need it.
Look at the terminated semicolon. You tell the compiler: no need in the value of expression, I want the expression side effect(s) only.

The C++ language specification does not depend on compilers or processors. The C++ references are not addresses of anybody (of course, a compiler uses memory addresses to implement reference processing).
 
Hello ArkM,
Yes, that does help. I got the book Accelerated C++, and the previous posts of this thread along with the first chapter or so of the book had just put me down the line of thinking you just presented. Your post helped solidify that position.

Lets see if I can rephrase this correctly.

Code:
a = b = c:
is treated as
a = (b = c);
The compiler updates b and returns, what I picture as, internal or implicit refernece to the updated b and uses that in the new expression and statement
Code:
a = the_updated_b;

Thank you for your persistance, time, and patience.

We need to know what a dragon is
before we study its anatomy.
(Bryan Kelly, 2010)
 
Yes, your explanation of a = b = c semantics is absolutely correct now.

Glad to help you.
Good luck!
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top