| | |
Overloading assignment operator
Please support our C++ advertiser: Intel Parallel Studio Home
![]() |
•
•
•
•
Originally Posted by comwizz
Why cant we overload assignment operator using a friend function?
operator= can only be a member function. It is intimately connected to the object on the left side of the =.If it was possible to define
operator= globally, then you might attempt to redefine the built-in = sign C++ Syntax (Toggle Plain Text)
int operator=(int, userdefinedtype);
operator= as member function. •
•
•
•
Originally Posted by sunnypalsingh
It is intimately connected to the object on the left side of the = •
•
•
•
If it was possible to defineoperator=globally, then you might attempt to redefine the built-in = sign
C++ Syntax (Toggle Plain Text)
int operator=(int, userdefinedtype);
Thanks for your help,
comwizz
>operator= can only be a member function.
Correct.
>It is intimately connected to the object on the left side of the =.
Yes, but not so intimately (ie. constructor or destructor) that a non-member function is completely illogical. You could, if C++ allowed it, do this, and nobody would question how reasonable it is:
>If it was possible to define operator= globally, then you might attempt to redefine the built-in = sign
That's a different issue entirely. It's trivial for an implementation to allow a non-member operator= but disallow defining it on built-in types. The reason operator= is required to be a member is because operator= has default behavior. If you redefine it globally, there's a distinct threat of a = b meaning different things to different parts of the code. Consider this:
foo doesn't know that operator= was redefined because function declarations are positional. If you declare an overload after you use the function, the overload isn't recognized. So foo will use the default operator=, which performs a shallow copy and ends up aliasing the pointer in c with the transient pointer in scratch that will get destroyed when foo returns. Therefore you have a memory leak, data loss, *and* an unexpected pointer to freed memory, whereas bar has none of these problems because it uses the overloaded operator= and correctly performs a deep copy.
Correct.
>It is intimately connected to the object on the left side of the =.
Yes, but not so intimately (ie. constructor or destructor) that a non-member function is completely illogical. You could, if C++ allowed it, do this, and nobody would question how reasonable it is:
C++ Syntax (Toggle Plain Text)
class C { friend void operator= ( C& lhs, const C& rhs ); }; void operator= ( C& lhs, const C& rhs ) { // Assign rhs to lhs }
That's a different issue entirely. It's trivial for an implementation to allow a non-member operator= but disallow defining it on built-in types. The reason operator= is required to be a member is because operator= has default behavior. If you redefine it globally, there's a distinct threat of a = b meaning different things to different parts of the code. Consider this:
C++ Syntax (Toggle Plain Text)
struct C { // Default operator= (shallow copy) char *p; }; void foo ( C& c ) { C scratch; // Work with scratch c = scratch; } void operator= ( C& lhs, const C& rhs ) { // Assign rhs to lhs (deep copy) } void bar ( C& c ) { C scratch; // Work with scratch c = scratch; } int main() { C test; foo ( test ); bar ( test ); }
New members chased away this month: 4
•
•
•
•
foo doesn't know that operator= was redefined because function declarations are positional. If you declare an overload after you use the function, the overload isn't recognized. So foo will use the default operator=, which performs a shallow copy and ends up aliasing the pointer in c with the transient pointer in scratch that will get destroyed when foo returns. Therefore you have a memory leak, data loss, *and* an unexpected pointer to freed memory, whereas bar has none of these problems because it uses the overloaded operator= and correctly performs a deep copy.
Thanks for your help,
comwizz
>So why not use the assignment operator overloading as a friend function
>by declaring and defining it above other functions
Indeed, why not? Just make sure that you get it right for any possible combination of functions and declarations in any number and combination of source files. And also keep a sticky note on your monitor to remind you of such a subtle problem that not even lint can warn you about. Also, don't forget that you need to watch for it in other people's code and any code you maintain, for a seemingly innocent change could introduce serious and difficult to find bugs.
The point is that it's very difficult to error check this problem in any non-trivial project. It's also so subtle that even programmers who are aware of it will be hard pressed to avoid it, much less the more numerous programmers who wouldn't even know the problem exists until it bites them in the ass. Compare that to the current state of affairs where a simple rule avoids the problem entirely, and the simple rule can't be missed because it gives you a compile time error if you don't follow it.
A guiding rule in the design of C++ is that a compile time error is much more desirable than a runtime error.
>by declaring and defining it above other functions
Indeed, why not? Just make sure that you get it right for any possible combination of functions and declarations in any number and combination of source files. And also keep a sticky note on your monitor to remind you of such a subtle problem that not even lint can warn you about. Also, don't forget that you need to watch for it in other people's code and any code you maintain, for a seemingly innocent change could introduce serious and difficult to find bugs.
The point is that it's very difficult to error check this problem in any non-trivial project. It's also so subtle that even programmers who are aware of it will be hard pressed to avoid it, much less the more numerous programmers who wouldn't even know the problem exists until it bites them in the ass. Compare that to the current state of affairs where a simple rule avoids the problem entirely, and the simple rule can't be missed because it gives you a compile time error if you don't follow it.
A guiding rule in the design of C++ is that a compile time error is much more desirable than a runtime error.
New members chased away this month: 4
![]() |
Similar Threads
- copy constructor & assignment operator overload problems (C++)
- Overloading the increment operator plz help (C++)
- assignment operator for a 3d array (C++)
Other Threads in the C++ Forum
- Previous Thread: error C2064: term does not evaluate to a function taking 1 arguments
- Next Thread: C++ For Loop Question
Views: 11628 | Replies: 6
| Thread Tools | Search this Thread |
Tag cloud for C++
6 api array arrays based beginner binary bmp c++ c/c++ calculator char class classes code compile compiler console conversion convert count data delete deploy dll download dynamic dynamiccharacterarray encryption error file format forms fstream function functions game givemetehcodez graph gui homeworkhelp iamthwee ifstream input int java lib library lines linker list loop looping loops map math matrix memory newbie news number output pointer problem program programming project python random read recursion recursive reference return rpg search simple sort spoonfeeding string strings struct temperature template templates text text-file tree url variable vector video visual visualstudio void win32 windows winsock wordfrequency wxwidgets






