It is one of the special member functions, which means that a default version of it is generated automatically by the compiler if the programmer does not declare one.
The default version performs a memberwise copy, where each member is copied by its own copy assignment operator (which may also be programmer-declared or compiler-generated).
The problem here is that if you’re trying to transactionize the assignment, so that either all of it happens or none of it happens, this breaks that.
If an exception occurs trying to new up might succeed, changing the object, and we only want to change the object if we can carry out the whole assignment operation.
Here it means the same thing: when the function returns a value, it will be the actual object we return, not a copy (normally, returning a value does make a copy).
Likewise, we use it means that the two strings are literally the same object, because they have the same address.
One interesting consequence of this is that you can imagine a class with a fairly deep inheritance chain where every class up the chain has other objects it owns.
You’d call an assignment operator low in the chain, it’d create the objects it needs, then it’d call its parent, which would create the objects it needs and call its parent, and so on up the chain.
So the allocations happen in one order and the assignments and deletions happen in reverse order, which feels kind of awkward at first glance, but it gets the job done.
It also means that there has to be enough free memory to hold two instances of every subobject, but there really isn’t a safe way around allocating all the extra memory.