Talk:Assignment operator (C++)

Latest comment: 12 years ago by Tigrisek in topic Unclear material

Example code – exception safety edit

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 edit

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" edit

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
I've added this ref as external reference. AgadaUrbanit (talk) 12:49, 30 December 2011 (UTC)Reply

Undid unjustified changes breaking the code edit

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 edit

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 edit

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);
    • Agreed. (a=b).NonConstMethod() is a good example for that. I'm not sure that returning const can make the class incompatible with standard containers. An example would be educational. Notinlist (talk) 15:20, 8 November 2011 (UTC)Reply
      • The C++ standard (23.2.1.4, table 96 – Container requirements) explicitly says that the return type of expression r = a must be X&. This means that any standard library implementation is free to contain code like, say, swap(a = b, c). Whether any of them actually does – I don't know, but this doesn't change the fact that using a type returning const X& would be violation of the requirements.Tigrisek (talk) 22:34, 8 November 2011 (UTC)Reply
  • 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
    • It's not a production system, but something like a textbook. It is good to have the irrelevant things also right, even with risking of breaking something, because that too can be repaired later. Notinlist (talk) 15:20, 8 November 2011 (UTC)Reply
    • Correcting as your first two bullet-points say is perfect. Otherwise I still believe that I improved the grammar, simplicity, consistency and explanatory value to a fair degree. Can I / should I work on this matter again? Notinlist (talk) 15:20, 8 November 2011 (UTC)Reply
      • Sure, improvements in grammar and consistency are always welcome. What I mean is that there's a border after which "improvement" is only subjective. Now you "fix" the code to int *ptr, tomorrow another person comes and "fixes" it to int * ptr because this is how the person believes it should be, the next day someone else will change it to int* ptr. There are many valid conventions and it's pointless to change an article if it uses one of them consistently.Tigrisek (talk) 22:34, 8 November 2011 (UTC)Reply
        • True. There were unnecessary "improvements" too. Notinlist (talk) 10:16, 9 November 2011 (UTC)Reply

Unclear material edit

Could someone provide a quote from Herb Sutter; Andrei Alexandrescu (2005). C++ coding standards: 101 rules, guidelines, and best practices. Pearson Education. ISBN 978-0-321-11358-0. Retrieved 30 December 2011. The existing ref does not mention book's pages and this swap approach to assignment appears fishy to me. So meanwhile I'm removing the ref and the cited material (see diff) till clarification is provided. AgadaUrbanit (talk) 12:53, 30 December 2011 (UTC)Reply

I've reverted the changes. I'm not going to type the whole quote from the reference (item 56, page 100), but it contains exactly the same code as the article (modulo naming and comments). I see nothing "fishy" in it, it is a known and recommended coding practice.Tigrisek (talk) 16:17, 1 January 2012 (UTC)Reply