>[!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; > } > > ... >} >```