Рекомендуемое чтение: Эффективный C ++ Скотт Мейерс. Вы найдете очень хорошее объяснение по этой теме (и многое другое) там.
Вкратце, если вы вернетесь по значению, конструктор копирования и деструктор будут задействованы по умолчанию (если компилятор не оптимизирует их - это то, что происходит в некоторых ваших случаях).
Если вы возвращаете по ссылке (или по указателю) переменную, которая является локальной (созданной в стеке), вы вызываете проблемы, потому что объект разрушается при возврате, поэтому в результате вы получаете висячую ссылку.
Канонический способ создать объект в функции и вернуть его по значению, например:
MyClass fun() {
return MyClass(a, b, c);
}
MyClass x = fun();
Если вы используете это, вам не нужно беспокоиться о правах собственности, свисающих ссылках и т. Д. И компилятор, скорее всего, оптимизирует дополнительные вызовы конструктора / деструктора копирования, поэтому вам не нужно беспокоиться о производительность либо.
Можно вернуть по ссылке объект, созданный с помощью new
(то есть в куче) - этот объект не будет уничтожен при возвращении из функции. Однако вы должны явно уничтожить его где-нибудь позже, вызвав delete
.
Технически возможно также сохранить объект, возвращаемый по значению, в ссылке, например:
MyClass& x = fun();
Однако, AFAIK, в этом нет особого смысла. Тем более что эту ссылку можно легко передать другим частям программы, которые находятся за пределами текущей области; однако объект, на который ссылается x
, является локальным объектом, который будет уничтожен, как только вы покинете текущую область. Так что этот стиль может привести к неприятным ошибкам.