== Why is this an issue?

{cpp} does not support polymorphic copy or move assignment operators. For example, the signature of a copy assignment operator on a "Base" class would be ``++Base& operator=(const Base& other)++``.


And on a "Derived" class that extends "Base", it would be ``++Derived& operator=(const Derived& other)++``.


Because these are two entirely different method signatures, the second method does not override the first, and adding ``++virtual++`` to the "Base" signature does not change which method is called.


It is possible to add an ``++operator=++`` override in a derived class, but doing so is an indication that you may need to reexamine your application architecture.


=== Noncompliant code example

[source,cpp]
----
class Base {
public:
  virtual Base& operator=(const Base& other); // Noncompliant
};

class Derived : public Base {
public:
  Derived& operator=(const Derived& other);
};
----


=== Compliant solution

[source,cpp]
----
class Base {
protected:
  Base& operator=(const Base& other); // not virtual
};

class Derived : public Base {
public:
  Derived& operator=(const Derived& other);
};
----


== Resources

* {cpp} Core Guidelines - https://github.com/isocpp/CppCoreGuidelines/blob/e49158a/CppCoreGuidelines.md#c60-make-copy-assignment-non-virtual-take-the-parameter-by-const-and-return-by-non-const[C.60: Make copy assignment non-`virtual`, take the parameter by `const&`, and return by non-`const&`]
* {cpp} Core Guidelines - https://github.com/isocpp/CppCoreGuidelines/blob/e49158a/CppCoreGuidelines.md#c63-make-move-assignment-non-virtual-take-the-parameter-by\--and-return-by-non-const[C.63: Make move assignment non-`virtual`, take the parameter by `&&`, and return by non-`const&`]


ifdef::env-github,rspecator-view[]

'''
== Implementation Specification
(visible only on this page)

=== Message

Remove this "virtual" specifier; polymorphism should not be used with assignment operators.


=== Highlighting

``++virtual++`` keyword


'''
== Comments And Links
(visible only on this page)

=== relates to: S1023

=== on 27 Jun 2016, 21:46:17 Ann Campbell wrote:
\[~alban.auzeill] I've made some edits, but I'm not done. I'm stuck on


____
After a copy using the "Base" interface, the integrity of a "Derived" object is compromised. Variables declared on "Base" contain new values, but those declared on "Derived" still have old values.

____

the meaning of which is not clear to me. It almost sounds like you expect the operation to have updated the "d" object, but surely I'm mis-reading that...?


I'll have a little time tomorrow, and more on Wednesday to discuss this.



=== on 28 Jun 2016, 09:30:36 Alban Auzeill wrote:
\[~ann.campbell.2]  Before the sentence "After a copy...", there's a code example and before there's: if "b" is a "Derived" object

In my example, "d" is not updated, it can be called "source". Only "b" is updated, it can be called "dest".

But, I notice that the reader can misunderstood my sentence starting by "After a copy..." because he doesn't remember or understand that "b" is a "Derived" passed to the function through the "Base" interface, we should find a way to make it obvious.

=== on 29 Jun 2016, 17:11:38 Alban Auzeill wrote:
I have renamed the variable in the code example so it's more obvious:

____
After a copy using the "Base" interface, when the parameter "dst" is a "Derived" object, its integrity is compromised. Variables of "dst" declared on "Base" class contain new values, but those declared on "Derived" class still have old values.

____

=== on 29 Jun 2016, 18:01:37 Ann Campbell wrote:
\[~alban.auzeill] I've simplified this to (I hope) focus on the core of the issue. Let me know if you feel I've removed too much.

endif::env-github,rspecator-view[]
