Jump to content

Talk:Assignment operator (C++)

Page contents not supported in other languages.
From Wikipedia, the free encyclopedia
This is an old revision of this page, as edited by Tigrisek (talk | contribs) at 21:18, 7 November 2011 (Reverting edits by Notinlist). The present address (URL) is a permanent link to this revision, which may differ significantly from the current revision.
WikiProject iconComputing Start‑class Low‑importance
WikiProject iconThis article is within the scope of WikiProject Computing, a collaborative effort to improve the coverage of computers, computing, and information technology on Wikipedia. If you would like to participate, please visit the project page, where you can join the discussion and see a list of open tasks.
StartThis article has been rated as Start-class on Wikipedia's content assessment scale.
LowThis article has been rated as Low-importance on the project's importance scale.
WikiProject iconC/C++ Unassessed High‑importance
WikiProject iconThis article is within the scope of WikiProject C/C++, a collaborative effort to improve the coverage of C and C++ topics on Wikipedia. If you would like to participate, please visit the project page, where you can join the discussion and see a list of open tasks.
???This article has not yet received a rating on Wikipedia's content assessment scale.
HighThis article has been rated as High-importance on the importance scale.

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 ints). 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)[reply]

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)[reply]

You're absolutely right, I've just fixed the code.Tigrisek (talk) 20:32, 22 October 2008 (UTC)[reply]

Add somewhere a Reference to "The Anatomy of the Assignment Operator"

Just as background information.

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)[reply]

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)[reply]

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)[reply]

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)[reply]

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)[reply]

In the above code, you want to overwrite the value of foo with the value of bar, then you want to overwrite the value of foo (again!!!) with the value of sth? Then why is the first assignment? What is the point?
It is more likely that you want to do foo = bar = sth which means foo = (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)[reply]
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
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 to AClass. 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)[reply]
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)[reply]

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.

Tigrisek (talk) 21:18, 7 November 2011 (UTC)[reply]