Talk:Assignment operator (C++)
![]() | Computing Start‑class Low‑importance | |||||||||
|
![]() | C/C++ Unassessed High‑importance | |||||||||
|
Example code – exception safety
The example given modifies the state of the object before all operations which might throw exceptions have completed; therefore, the example is not exception-safe. Also, it uses a built-in array, which makes exception safety difficult in general (though not for int
s). Using std::vector<int> array;
instead of int *array;
would make exception-safety easier [1]:
class My_Array { int count; std::vector<int> array; public: // Copy constructor My_Array(const My_Array& orig) : count(orig.count), array(orig.array) { /* EMPTY */ } // Non-throwing swap void Swap(My_Array& orig) { using std::swap; swap(count, orig.count); swap(array, orig.array); } My_Array& operator=(const My_Array& rhs) { My_Array tmp(rhs); Swap(tmp); return *this; } };
- I have just refactored the code to be exception-safe. However, I've left the built-in array to show the implementation in case of manual resource management.--Tigrisek 22:22, 20 September 2007 (UTC)
Example code – Koenig Lookup
I have undid the revision since Koenig Lookup would have the same effect in this case, there's no need to complicate the code.
Surely
std::copy(new_array, new_array + other.count, other.array);
should be
std::copy(other.array, other.array + other.count, new_array);
? The code as-written copies from freshly allocated memory over the original :-( 213.248.204.106 (talk) 09:45, 20 October 2008 (UTC)
- You're absolutely right, I've just fixed the code.Tigrisek (talk) 20:32, 22 October 2008 (UTC)
Add somewhere a Reference to "The Anatomy of the Assignment Operator"
Just as background information.
- http://icu-project.org/docs/papers/cpp_report/the_anatomy_of_the_assignment_operator.html
- http://icu-project.org/docs/papers/cpp_report/the_assignment_operator_revisited.html —Preceding unsigned comment added by 213.173.183.22 (talk) 10:18, 27 February 2009 (UTC)
Regarding the anatomy of assignment operator: Keep in mind that the referenced paper show a faulty assignment operator. If the TSuperFoo assignment throws exception you willl have created objects with pointers on stack bar1 and bar2 that is never deleted. — Preceding unsigned comment added by 136.249.251.200 (talk) 11:45, 28 September 2011 (UTC)
- In any case the article in question is from 1997, even before the initial C++ Standard, ISO/IEC 14882:1998 was released. As such, there may be more errors or inaccuracies. Regards,
decltype
(talk) 14:23, 28 September 2011 (UTC)
Undid unjustified changes breaking the code
I have reverted the example to the previous form, which is in most regards equal to the new one, but according to the cited reference (that has also been removed with the changes) it is preferred as possibly more optimiser-friendly. Moreover, IIRC, the new code would not compile at all (calling non-const member function on a temporary).Tigrisek (talk) 20:56, 27 July 2009 (UTC)
- I endorse this. It is idiomatic, and supported by a source. The other example is not ill-formed, however (it is fine to call a non-const member function of a temporary). Regards, decltype (talk) 21:35, 27 July 2009 (UTC)
Constant return type
Why are the assignment operators in article declared with constant return type? This is not the correct declaration of an assignment operator! How else one could compile something like this?
AClass foo, bar, sth; ... (foo = bar) = sth;
With a correct assignment operator compilation of the above code would not fail. 192.100.112.210 (talk) 14:36, 26 October 2011 (UTC)
- In the above code, you want to overwrite the value of
foo
with the value ofbar
, then you want to overwrite the value offoo
(again!!!) with the value ofsth
? Then why is the first assignment? What is the point? - It is more likely that you want to do
foo = bar = sth
which meansfoo = (bar = sth)
which does not require non-const return. I see that the net is filled with the example of defining assignment overloading with non-const reference return. I think it's just laziness, because I cannot see the codes that rely on that. Notinlist (talk) 13:06, 28 October 2011 (UTC)- Perhaps my custom assignment operator could have some side effect like increasing a static counter or whatever else, that's why I'd like
foo = bar
to be performed. It's not about the purpose, as one can find plenty of it if he really wants. It's simply just because basic types, like
- Perhaps my custom assignment operator could have some side effect like increasing a static counter or whatever else, that's why I'd like
int a=1, b=2, c=3; (a=b)=c;
- would work as well. Or, more practically and much more probably, someone would expect such a piece of code to work:
AClass foo, bar; (...) afunction(foo = bar);
- where
afunction
takes non-const reference toAClass
. It works with default assignment operator and so it should with user-defined, unless constant return type is desired for a specific reason, of course. In such a case, it is a custom operator signature and goes beyond the topic, doesn't it? — Preceding unsigned comment added by 178.235.27.121 (talk) 19:18, 7 November 2011 (UTC)
- where
- Agreed, I have dropped the const-qualifier from the return type of the assigment operator. It is the canonical form of the operator. Consider the Standard Library requirements. From a standard library perspective, a class T with a copy assignment operator whose return type is "reference to const T" can not even be considered an Assignable type. Consider also that the implicitly generated assignment operator for a class returns "reference to T".
decltype
(talk) 20:02, 7 November 2011 (UTC)
- Agreed, I have dropped the const-qualifier from the return type of the assigment operator. It is the canonical form of the operator. Consider the Standard Library requirements. From a standard library perspective, a class T with a copy assignment operator whose return type is "reference to const T" can not even be considered an Assignable type. Consider also that the implicitly generated assignment operator for a class returns "reference to T".
Reverting edits by Notinlist
I'm reverting the edits because they have several issues:
- the order: first acquire new resources, then release the old ones is crucial for exception safety;
- the canonical form of copy assignment returns non-const reference according to the cited source (otherwise the objects would be incompatible with standard containers);
- don't edit the code only to change irrelevant stuff like argument names or spacing around * - it's a matter of personal liking and does not improve the quality of the article, yet it's just an opportunity to accidentally break something.