Не возвращать ссылки, возврат по значению:
std::string function() // no ref
{
string s = "Faz";
s += "Far";
s += "Boo";
return s;
}
Если ваш компилятор может выполнить именованную оптимизацию возвращаемого значения, также известную как NRVO (что вероятно), он преобразует это в нечто примерно эквивалентное следующему, что исключает любые посторонние копии:
// Turn the return value into an output parameter:
void function(std::string& s)
{
s = "Faz";
s += "Far";
s += "Boo";
}
// ... and at the callsite,
// instead of:
std::string x = function();
// It does this something equivalent to this:
std::string x; // allocates x in the caller's stack frame
function(x); // passes x by reference
Относительно дополнительного вопроса:
Конструктор копирования строки всегда делает глубокое копирование. Так что, если есть вовлеченные копии, нет проблем с наложением. Но при возврате по значению с помощью NRVO, как вы можете видеть выше, копии не создаются.
Вы можете делать копии, используя несколько различных синтаксисов:
string orig = "Baz";
string copy1 = string(orig);
string copy2(orig);
string copy3 = orig;
Второе и третье не имеют семантической разницы: они оба просто инициализация. Первый создает временный объект, явно вызывая конструктор копирования, а затем инициализирует переменную копией. Но компилятор может сделать здесь elision copy (и очень вероятно, что так и будет) и сделает только одну копию.