Ваше решение не возвращает мусор, если у вас есть конструктор рабочей копии - объект String tmp
копируется в объект результата до того, как он будет уничтожен в конце блока.
Вы могли бы сделать это лучше, заменив
String tmp;
tmp.Set(this->mString);
с
String tmp(*this);
(для этого вам нужен правильно работающий конструктор копирования, но он все равно нужен для вашего return
оператора)