В трех случаях вторая строка является общей:
MyType t = myFunction();
Эта строка получает результат вызова myFunction
и использует его для copy-construct нового элемента MyType
с именем t
.
Теперь о различиях. В первом случае вы возвращаете по значению, что означает (семантически), что компилятор создаст копию объекта, содержащегося в операторе return
внутри myFunction
, а затем использует эту копию в качестве источника для построения копии. t
. Компилятор, скорее всего, исключит копии (по крайней мере, второй).
В двух других случаях функции возвращают ссылки на какой-либо другой объект. Если объекты являются локальными, то это неопределенное поведение. Разница между ними заключается в том, может ли возвращенная ссылка использоваться для изменения упомянутого объекта или нет, и это может повлиять на то, какой конструктор копирования используется, или его можно использовать вообще. Помните, что объект, с которого вы получаете ссылку, должен пережить вызов функции, иначе вы будете вызывать неопределенное поведение.
// an example where it matters:
typedef std::auto_ptr<int> MyType;
MyType t = myFunction();
Поскольку std::auto_ptr
изменяет правую часть при назначении, предыдущий код будет работать только в том случае, если возвращаемая ссылка неконстантна.
Лучиан указывает, что возвращение ссылки , скорее всего, будет неопределенным поведением , так когда бы это было не так? Когда объект, из которого была получена ссылка, переживает использование ссылки. Это основной строительный блок синглтона Meyers:
// an example where returning a reference is correct
MyType & myFunction() {
static MyType instance; // Note static storage duration!
return instance;
}
Или любой простой метод доступа, который возвращает ссылку на подобъект. Некоторые из распространенных случаев - operator[]
в контейнерах (обычно они не копируют значение, а возвращают ссылку на сохраненные данные).
Но это правда, что чаще всего функции возвращают статически не живые объекты, а локальные.