>[!note]
A special form of [[Operator Overloading]] that relates to the [[Rule of 3]].
A copy assignment is the overload for `=`. For any primitive, it should make sense that when you use the operator it copies one value to another.
>[!example]
>```cpp
>// make memory for a new variable 'a'
>int a;
>
>// the '=' operator will copy the value on the right to the lvalue on the left
>a = 420;
>// the value 420 has been copied into a
>```
This makes sense for [[Primitives]], but copy assignment overloading comes into play when you have your own classes.
Take the [[CString]] example, where each instance of `CString` has its own `char* buffer`, which is a [[Heap]] allocated string that is deleted in `CString`'s [[Destructor]].
Without a custom copy assignment overload, if we did something like this with CString, the default `=` operator will simply *copy all the bytes* from the source to the destination (`destination = source;`).
```cpp
int main() {
// new buffer ['b', 'r', 'u', 'h', '\0'] (buff1)
CString str1{"bruh"};
// new buffer ['h', 'u', 'h', '\0'] (buff2)
CString str2{"huh"};
// copies all bytes of str2 to str1
str1 = str2;
// str1.~CString(), tries to delete buff2
// str2.~CString(), tries to delete buff2
// buff1 is never deleted, memory leak
}
```
Because `CString` has heap allocated data, as well as because `CString` has delicate relations with its heap allocated data to ensure that there is only one instance of `CString` to free said data, we need a custom copy assignment operator in order to do a *deep copy*.
>[!example]
>```cpp
>class CString {
> ...
> CString& operator=(const CString& from) {
> // clean up current buffer
> delete[] buffer;
>
> length = from.length;
> buffer = new char[length + 1];
>
> // copy string contents 'from' -> 'this'
> std::memcpy(buffer, from, length * sizeof(char));
>
> // add NULL termination
> buffer[length] = '\0';
> return *this;
> }
>
> ...
>}
>```