Compiler generated assignment operator= question
-
Suppose I have a class with a few member variables, and one of them is a
CArray
object, e.g.:CMyClass { ... private: int var1, var2, var3; bool flag1, flag2, flag3; CArray arSomeArray; };
If I didn't have that CArray member, I could simply write:
CMyClass a, b; a = b;
The assignment operator would be simply generated by compiler. But when
CArray
is there, compiler cannot generate default assigment operator, so I have to add to the class:CMyClass& operator= (CMyClass& src){ var1 = src.var1; var2 = src.var2; var3 = src.var3; flag1 = src.flag1; flag2 = src.flag2; flag3 = src.flag3; arSomArray.Copy (src.arSomeArray); return *this; }
Not only that it is very tedious writing a few dozen of "
x = src.x
", it is also prone to bugs. Like later I will add a variable to the class and might forget to add it to theoperator=
function. Is there a way to write something like below?CMyClass& operator= (CMyClass& src){ dear_compiler_do_what_you_can_with_all_the_variables_i_ll_take_care_of_the_rest(); arSomArray.Copy (src.arSomeArray); return *this; }
Thanks
-
Suppose I have a class with a few member variables, and one of them is a
CArray
object, e.g.:CMyClass { ... private: int var1, var2, var3; bool flag1, flag2, flag3; CArray arSomeArray; };
If I didn't have that CArray member, I could simply write:
CMyClass a, b; a = b;
The assignment operator would be simply generated by compiler. But when
CArray
is there, compiler cannot generate default assigment operator, so I have to add to the class:CMyClass& operator= (CMyClass& src){ var1 = src.var1; var2 = src.var2; var3 = src.var3; flag1 = src.flag1; flag2 = src.flag2; flag3 = src.flag3; arSomArray.Copy (src.arSomeArray); return *this; }
Not only that it is very tedious writing a few dozen of "
x = src.x
", it is also prone to bugs. Like later I will add a variable to the class and might forget to add it to theoperator=
function. Is there a way to write something like below?CMyClass& operator= (CMyClass& src){ dear_compiler_do_what_you_can_with_all_the_variables_i_ll_take_care_of_the_rest(); arSomArray.Copy (src.arSomeArray); return *this; }
Thanks
Not using CArray would be a good start :-D MFC's container classes suck. Try using a stl container instead, it might just change your life. Ryan
-
Not using CArray would be a good start :-D MFC's container classes suck. Try using a stl container instead, it might just change your life. Ryan
I agree 100%. I've used the MFC containers for years but STL is much more powerful and more portable. I wish I switched a long time ago. Try std::vector John
-
Suppose I have a class with a few member variables, and one of them is a
CArray
object, e.g.:CMyClass { ... private: int var1, var2, var3; bool flag1, flag2, flag3; CArray arSomeArray; };
If I didn't have that CArray member, I could simply write:
CMyClass a, b; a = b;
The assignment operator would be simply generated by compiler. But when
CArray
is there, compiler cannot generate default assigment operator, so I have to add to the class:CMyClass& operator= (CMyClass& src){ var1 = src.var1; var2 = src.var2; var3 = src.var3; flag1 = src.flag1; flag2 = src.flag2; flag3 = src.flag3; arSomArray.Copy (src.arSomeArray); return *this; }
Not only that it is very tedious writing a few dozen of "
x = src.x
", it is also prone to bugs. Like later I will add a variable to the class and might forget to add it to theoperator=
function. Is there a way to write something like below?CMyClass& operator= (CMyClass& src){ dear_compiler_do_what_you_can_with_all_the_variables_i_ll_take_care_of_the_rest(); arSomArray.Copy (src.arSomeArray); return *this; }
Thanks
You could declare all the members you want automatically copied in a structure defined within the class - C++ will then generate an assignment operator for that structure. e.g. class Blah { private: struct Hidden { int a; int b; }; Hidden h; CArray<int,int> array; Blah& operator=(const Blah& copy) { h = copy.h; // Copy the array... } }; However, as others have pointed out, if you use STL you don't run into these problems. Dave http://www.cloudsofheaven.org
-
I agree 100%. I've used the MFC containers for years but STL is much more powerful and more portable. I wish I switched a long time ago. Try std::vector John
Thanks, but I am not going to rewrite a few hundred of classes, possibly breaking several projects along the way, just for this cause. Having CArray with all its upsides and downsides is a must.
-
Thanks, but I am not going to rewrite a few hundred of classes, possibly breaking several projects along the way, just for this cause. Having CArray with all its upsides and downsides is a must.
I know what you mean. I have a lot of code in several DLLs that sill has MFC containers and in most cases it is better not to rewrite but I wish I would have known stl in the first place. Anything new I will use stl containers instead of MFC. John
-
You could declare all the members you want automatically copied in a structure defined within the class - C++ will then generate an assignment operator for that structure. e.g. class Blah { private: struct Hidden { int a; int b; }; Hidden h; CArray<int,int> array; Blah& operator=(const Blah& copy) { h = copy.h; // Copy the array... } }; However, as others have pointed out, if you use STL you don't run into these problems. Dave http://www.cloudsofheaven.org
The idea is good, however separating some variables into a structure just for coding convinience would not make sense to someoneelse reading the code.
-
Suppose I have a class with a few member variables, and one of them is a
CArray
object, e.g.:CMyClass { ... private: int var1, var2, var3; bool flag1, flag2, flag3; CArray arSomeArray; };
If I didn't have that CArray member, I could simply write:
CMyClass a, b; a = b;
The assignment operator would be simply generated by compiler. But when
CArray
is there, compiler cannot generate default assigment operator, so I have to add to the class:CMyClass& operator= (CMyClass& src){ var1 = src.var1; var2 = src.var2; var3 = src.var3; flag1 = src.flag1; flag2 = src.flag2; flag3 = src.flag3; arSomArray.Copy (src.arSomeArray); return *this; }
Not only that it is very tedious writing a few dozen of "
x = src.x
", it is also prone to bugs. Like later I will add a variable to the class and might forget to add it to theoperator=
function. Is there a way to write something like below?CMyClass& operator= (CMyClass& src){ dear_compiler_do_what_you_can_with_all_the_variables_i_ll_take_care_of_the_rest(); arSomArray.Copy (src.arSomeArray); return *this; }
Thanks
What about writing a quick subclass of CArray that defines operator= and simply calls CArray::Copy()? That would still be compatible with your other class that just use CArray. --Dean
-
The idea is good, however separating some variables into a structure just for coding convinience would not make sense to someoneelse reading the code.
I agree it would look weird and non-intuative - which is while i recommend STL. Dave http://www.cloudsofheaven.org
-
Suppose I have a class with a few member variables, and one of them is a
CArray
object, e.g.:CMyClass { ... private: int var1, var2, var3; bool flag1, flag2, flag3; CArray arSomeArray; };
If I didn't have that CArray member, I could simply write:
CMyClass a, b; a = b;
The assignment operator would be simply generated by compiler. But when
CArray
is there, compiler cannot generate default assigment operator, so I have to add to the class:CMyClass& operator= (CMyClass& src){ var1 = src.var1; var2 = src.var2; var3 = src.var3; flag1 = src.flag1; flag2 = src.flag2; flag3 = src.flag3; arSomArray.Copy (src.arSomeArray); return *this; }
Not only that it is very tedious writing a few dozen of "
x = src.x
", it is also prone to bugs. Like later I will add a variable to the class and might forget to add it to theoperator=
function. Is there a way to write something like below?CMyClass& operator= (CMyClass& src){ dear_compiler_do_what_you_can_with_all_the_variables_i_ll_take_care_of_the_rest(); arSomArray.Copy (src.arSomeArray); return *this; }
Thanks
There is a problem in your assignment operator. If someone assigns an object to itself your code will fail on dynamic data such as CArray. For example: CMyClass A; A=A; //What happens to arSomArray? To solve this I create a private destroy() and copy() functions and implement the copy constructor and assignment operator as follows: PROPERTY::~PROPERTY() { destroy(); } PROPERTY::PROPERTY(PROPERTY & other ) { copy(other); } PROPERTY& PROPERTY::operator =(PROPERTY & other ) { if ( &other != this ) { destroy(); copy( other ); } return *this; } copy() does the copy of data from one class to the other similar to what you did in your assignment operator destroy() deletes any dynamically allocated data. I have an idea to solve your problem that I will post a little bit later. John
-
There is a problem in your assignment operator. If someone assigns an object to itself your code will fail on dynamic data such as CArray. For example: CMyClass A; A=A; //What happens to arSomArray? To solve this I create a private destroy() and copy() functions and implement the copy constructor and assignment operator as follows: PROPERTY::~PROPERTY() { destroy(); } PROPERTY::PROPERTY(PROPERTY & other ) { copy(other); } PROPERTY& PROPERTY::operator =(PROPERTY & other ) { if ( &other != this ) { destroy(); copy( other ); } return *this; } copy() does the copy of data from one class to the other similar to what you did in your assignment operator destroy() deletes any dynamically allocated data. I have an idea to solve your problem that I will post a little bit later. John
Thank you for the reminder. I remember I've read some article on CodeProject about dangers of CArray such assigning to itself or from reference to itself. I will keep this in mind. As for the answer to my problem, Dean Goodman already answered it.
-
What about writing a quick subclass of CArray that defines operator= and simply calls CArray::Copy()? That would still be compatible with your other class that just use CArray. --Dean
Thank you. This is exactly the answer I was looking for! I derived a class from CArray and added operator= to it. Now compiler has no trouble generating default assignment. Everything works perfectly! :-D
-
Thank you for the reminder. I remember I've read some article on CodeProject about dangers of CArray such assigning to itself or from reference to itself. I will keep this in mind. As for the answer to my problem, Dean Goodman already answered it.
I was just writing some code for my idea... Anyways make sure you provide a copy constructor otherwise the complier would provide one and circumvent your code for the following code CMyClass a; CMyClass b = a; This code will not call the = operator. It uses the copy constructor... John