Spectator Global Risk Conference

Forum Navigation:


FORUMS > Programming and Software Forum < refresh >
Topic Title: Fun with assignment operators
Created On Wed Mar 24, 04 10:29 AM
Topic View:

View thread in raw text format


Nonius
Senior Member

Posts: 5131
Joined: Jan 2003

Wed Mar 24, 04 10:29 AM
User is offline View users profile

If you make an assignment operator like...

x operator = (const x&);

the destructor is called.

people tell me it is better to do...

x& operator = (const x&);

which does not invoke the destructor.

Can you give me some color on why the latter is better?

-------------------------
Nonius

I'm going to Hell with FDAX as my Kharnak.
 
Reply
   
Quote
   
Top
   
Bottom
     



Etuka
Senior Member

Posts: 304
Joined: Jan 2002

Wed Mar 24, 04 11:06 AM
User is offline

Misread the question (duh).

In the second case, you are not creating a temporary variable to return (this is the inefficiency). The destructor is called to get rid of the temporary.

Edited: Wed Mar 24, 04 at 11:10 AM by Etuka
 
Reply
   
Quote
   
Top
   
Bottom
     



HankScorpio
Member

Posts: 103
Joined: Mar 2004

Wed Mar 24, 04 12:07 PM
User is offline View users profile

Two points:

1. operator=() could have returned void. The reason it returns TypeX or TypeX&, is such that the following is valid:

objA = objB = objC = objD; // etc.....

2. operator=() (assuming it now returns TypeX or TypeX& to take care of the shennanigans in point 1 above) returns with the following line:

return *this;

If the method (operator overload) is defined as returning TypeX (i.e. by value) the copy constructor is invoked when operator=() returns an object by value, and then the destructor is invoked as the object goes out of scope.

If however the definition specifies the return type as TypeX&, no copy constructor is invoked, and hence no destructor is invoked at this specific point of code execution. This is the standard form of the overloaded assignment operator, i.e. return type is TypeX& (reference).

Try writing a noddy class with Constructor, Destructor, Copy Constructor and operator=() (known as Coplien canonical form). Then write a noddy main.cpp that creates objects and assigns them to each other. You can then single step through the code and print out debug messages to clarify this.

Also, whilst you are at it, check out overloading the ++ (or --) operator in preincrement/decrement and postincrement/decrement forms. You should now be able to figure out (if you don't already know that is) why ++object is more efficient than object++.

Cheers, Hank.

-------------------------
Hank Scorpio

Edited: Wed Mar 24, 04 at 12:11 PM by HankScorpio
 
Reply
   
Quote
   
Top
   
Bottom
     



Nonius
Senior Member

Posts: 5131
Joined: Jan 2003

Wed Mar 24, 04 12:55 PM
User is offline View users profile

Quote

Originally posted by: Etuka
Misread the question (duh).

In the second case, you are not creating a temporary variable to return (this is the inefficiency). The destructor is called to get rid of the temporary.


It would have gone over my head. I am completely self-learned in C++, although I have a certain OO mind. I just realized the thing about the destructor and the operator by shear experimination. for a real developer, this is obvious owing to the differences between passing a returning an object and a reference to an object.

-------------------------
Nonius

I'm going to Hell with FDAX as my Kharnak.
 
Reply
   
Quote
   
Top
   
Bottom
     



Nonius
Senior Member

Posts: 5131
Joined: Jan 2003

Wed Mar 24, 04 12:58 PM
User is offline View users profile

Quote

Originally posted by: HankScorpio
Two points:

1. operator=() could have returned void. The reason it returns TypeX or TypeX&, is such that the following is valid:

objA = objB = objC = objD; // etc.....

2. operator=() (assuming it now returns TypeX or TypeX& to take care of the shennanigans in point 1 above) returns with the following line:

return *this;

If the method (operator overload) is defined as returning TypeX (i.e. by value) the copy constructor is invoked when operator=() returns an object by value, and then the destructor is invoked as the object goes out of scope.

If however the definition specifies the return type as TypeX&, no copy constructor is invoked, and hence no destructor is invoked at this specific point of code execution. This is the standard form of the overloaded assignment operator, i.e. return type is TypeX& (reference).

Try writing a noddy class with Constructor, Destructor, Copy Constructor and operator=() (known as Coplien canonical form). Then write a noddy main.cpp that creates objects and assigns them to each other. You can then single step through the code and print out debug messages to clarify this.

Also, whilst you are at it, check out overloading the ++ (or --) operator in preincrement/decrement and postincrement/decrement forms. You should now be able to figure out (if you don't already know that is) why ++object is more efficient than object++.

Cheers, Hank.


thanks hank, when I sober up, I will try your suggestions. I am angry at myself because I love programming, but, quite frankly, a little knowledge is dangerous. I worked on this fuking memory leak for a long time and I thought it reduced to some stupid things I was doing with an assignment operator and a destructor...fuk man, I am pissed, I am possessed with fixing this sh it, and, unfortunately, I am a Class B or C programmer.



-------------------------
Nonius

I'm going to Hell with FDAX as my Kharnak.
 
Reply
   
Quote
   
Top
   
Bottom
     



Nonius
Senior Member

Posts: 5131
Joined: Jan 2003

Wed Mar 24, 04 01:02 PM
User is offline View users profile

I was up at 4AM thinking about this fuking memory leak....fuk I love and hate programming.

thing is, I am mostly self taught, but, I did pick up a few commandments from a coupla supposed gurus. One guru pontificated on the fact that you never, and I mean never, want public functions like, void SetValue(Y X), meaning that constructors should do that sheah, and if they don't do it, then assignments will do it. the aforementioned handwaver also said always make your data members private, or at least protected, and initially I abided by that. but, Nonius got lazy, and made things public and/or created SetValue functions. Oddly, I think part of my misery is EXACCLY related to this lazy tendency. Now, all hell is breaking loose.

-------------------------
Nonius

I'm going to Hell with FDAX as my Kharnak.

Edited: Wed Mar 24, 04 at 01:07 PM by Nonius
 
Reply
   
Quote
   
Top
   
Bottom
     



HankScorpio
Member

Posts: 103
Joined: Mar 2004

Wed Mar 24, 04 01:07 PM
User is offline View users profile

Nah, don't worry about it. Although I have a lot of experience with C++ and I believe it still has its uses, I consider it a pretty awful language. Much prefer Java and C#, as the memory leak issue you describe, is (almost) not an issue in these newer languages (you can still have live references in containers, databases connection objects need to be closed, etc, so its not all code-and-forget but its a lot easier). Also Java/C# references are not like C++ references, which can be though of as an "alias" and can be confusing when you first look at it.

I really need to get some metrics of C# code vs C++ code doing some heavy duty numerical work. Curious.....

Cheers, Hank.

-------------------------
Hank Scorpio
 
Reply
   
Quote
   
Top
   
Bottom
     



Nonius
Senior Member

Posts: 5131
Joined: Jan 2003

Wed Mar 24, 04 01:12 PM
User is offline View users profile

Quote

Originally posted by: HankScorpio
Nah, don't worry about it. Although I have a lot of experience with C++ and I believe it still has its uses, I consider it a pretty awful language. Much prefer Java and C#, as the memory leak issue you describe, is (almost) not an issue in these newer languages (you can still have live references in containers, databases connection objects need to be closed, etc, so its not all code-and-forget but its a lot easier). Also Java/C# references are not like C++ references, which can be though of as an "alias" and can be confusing when you first look at it.

I really need to get some metrics of C# code vs C++ code doing some heavy duty numerical work. Curious.....

Cheers, Hank.


I gotta learn that C# sheah, I feel like killing about 1012 French people now....ok, maybe I'll calm down. Pointers are dangerous weapon for someone like me....I even have used ** in this sheah, cuz I couldn't get the vector stuff to do what I wanted. fuk. gimme a gun.



-------------------------
Nonius

I'm going to Hell with FDAX as my Kharnak.
 
Reply
   
Quote
   
Top
   
Bottom
     



mj
Senior Member

Posts: 3030
Joined: Dec 2001

Wed Mar 24, 04 01:58 PM
User is offline View users profile

if you put a=b=c

then a becomes equal to c, whether the return type is X or X& or const X&



if you put

(a=b) = c

then a becomes equal to b and then equal to C if the return type is X&
if it is X, then a becomes equal b, and then a copy of a becomes equal to c and then disappears,

if it is const X& the code doesn't compile



more seriously, having a return type without the & means that an extra variable will be created and destroyed. However, unless you are into using the return value of assigment operators, which you probably aren't, it makes no difference.


Personally, i would use const X&, but the standard says that for all built-in types it will be X& so I generally go with that.





-------------------------
Quant Job Interview Questions and Answers now available on lulu.com and amazon.com
 
Reply
   
Quote
   
Top
   
Bottom
     



Crassus
Senior Member

Posts: 240
Joined: Jul 2003

Wed Mar 24, 04 02:25 PM
User is offline

the implemetation of those overloaded operators etc. can be reduced to 'formula' type use. e.g. you want to overload '=' then here is the formula. btw it is often better to use friend overloaded operators for more flexibility.
 
Reply
   
Quote
   
Top
   
Bottom
     



fizik
Member

Posts: 22
Joined: Jan 2006

Thu Jun 14, 07 03:46 PM
User is offline

Has anyone played with virtual operator=? Can it be useful?
What about other operators?
Thanks..

Edited: Thu Jun 14, 07 at 03:47 PM by fizik
 
Reply
   
Quote
   
Top
   
Bottom
     



Cuchulainn
Senior Member

Posts: 16557
Joined: Jul 2004

Thu Jun 14, 07 05:13 PM
User is offline View users profile

Quote

Has anyone played with virtual operator=? Can it be useful?

1) No, 2) No

Quote

What about other operators?

What's the question again?


-------------------------
www.datasimfinancial.com
 
Reply
   
Quote
   
Top
   
Bottom
     



fizik
Member

Posts: 22
Joined: Jan 2006

Fri Jun 15, 07 07:51 PM
User is offline

Well, if you google virtual assignment operator, it becomes clear that some people have given it a thought. I was wondering whether it was worth exploring at all. One problem that seems obvious is that if you declare

Base *pa (new Derived);
Base *pb (new Derived);

than mere *pa = *pb is disastrous since pa and pb may easily end up pointing to different children of Base. Cuchulainn probably has more fundamental issues in mind, and I appreciate the response.

The other question was whether any other operators could/should be made virtual. I guess not..
 
Reply
   
Quote
   
Top
   
Bottom
     



Cuchulainn
Senior Member

Posts: 16557
Joined: Jul 2004

Fri Jun 15, 07 10:05 PM
User is offline View users profile

Quote

Originally posted by: fizik
Well, if you google virtual assignment operator, it becomes clear that some people have given it a thought. I was wondering whether it was worth exploring at all. One problem that seems obvious is that if you declare

Base *pa (new Derived);
Base *pb (new Derived);

than mere *pa = *pb is disastrous since pa and pb may easily end up pointing to different children of Base. Cuchulainn probably has more fundamental issues in mind, and I appreciate the response.

The other question was whether any other operators could/should be made virtual. I guess not..


Well, my cryptic answer to your cryptic question
You have answered the question in fact. Assignment is kind of like a constructors and there is not virtual constructor. I redefine assignment in derived classes. It's got to do with memory layout.


Quote

This is an area of C++ where there is no single correct approach. Theoretically, the right thing is to always make assignment virtual, but doing so leads to problems of its own. Because of these trade-offs, whether to make assignment virtual is something you should consider carefully, in consultation with an architect.




-------------------------
www.datasimfinancial.com

Edited: Fri Jun 15, 07 at 10:12 PM by Cuchulainn
 
Reply
   
Quote
   
Top
   
Bottom
     



rwinston
Member

Posts: 52
Joined: Feb 2007

Sat Jun 16, 07 10:13 AM
User is offline

C++ will just give you enough rope to hang yourself with if you're careless, and its pretty easy to do! Experienced C++ coders would tend to use mechanisms like Boost shared pointers and the RAII idiom.
 
Reply
   
Quote
   
Top
   
Bottom
     



rwinston
Member

Posts: 52
Joined: Feb 2007

Sat Jun 16, 07 10:14 AM
User is offline

Right. But there is a virtual constructor idiom:

http://www.parashift.com/c++-faq-lite/virtual-functions.html#faq-20.8

 
Reply
   
Quote
   
Top
   
Bottom
     



Cuchulainn
Senior Member

Posts: 16557
Joined: Jul 2004

Sat Jun 16, 07 10:34 AM
User is offline View users profile

Quote

Originally posted by: rwinston
Right. But there is a virtual constructor idiom:

http://www.parashift.com/c++-faq-lite/virtual-functions.html#faq-20.8


Exactly, and this is the way to do it. It is safe. The standardised GOF name is Prototype.

prototype

The design vocabulary is now enriched and communcication becomes easier.

-------------------------
www.datasimfinancial.com

Edited: Sat Jun 16, 07 at 10:36 AM by Cuchulainn
 
Reply
   
Quote
   
Top
   
Bottom
     

View thread in raw text format
FORUMS > Programming and Software Forum < refresh >

Forum Navigation:

© All material, including contents and design, copyright Wilmott Electronic Media Limited - FuseTalk 4.01 © 1999-2010 FuseTalk Inc.