f()
возвращает ссылку на объект;возвращение из него не копирует какой-либо объект.g()
возвращает копию объекта, по крайней мере, концептуально.
std::vector<int>& f1 = f(); //reference
f1
относится к объекту, на который f()
вернул ссылку.Копии не сделаны.Константная квалификация ссылки здесь не имеет значения (что касается копирования; очевидно, это влияет на то, что можно сделать с объектом).
std::vector<int> f2 = f(); //value
f2
является копией объектана который f()
возвращена ссылка.
std::vector<int>& g1 = g(); //reference
Это недопустимо.Неконстантная ссылка не может быть связана с временным объектом.
Если ссылка является константно-квалифицированной, то эта строка фактически совпадает со следующей строкой: создается копия объекта, возвращенного g()
, ссылка привязывается к этой копии, и эта копиязадается время жизни ссылки (оно уничтожается, когда ссылка «уничтожается»).
std::vector<int> g2 = g(); //value
g2
- это копия объекта, возвращаемая g()
.Будет ли сделана копия (и сколько копий может быть сделано), зависит от оптимизации компилятора.
Что если f()
и g()
являются функциями-членами, и каждый возвращает данные члена, а не какие-то локальныепеременная?
Если f()
возвращает ссылку на локальную переменную, программа неверна и выдает неопределенное поведение, если вы пытаетесь использовать ссылку, потому что указанный объект перестает существовать, когда функция возвращается.
Если f()
возвращает ссылку на переменную-член, динамически размещенный объект или объект со статической или потоковой локальной памятью, тогда ссылка действительна в течение всего времени жизни этого объекта (или другого объекта).того же типа, созданного в том же месте в памяти, что и объект, на который была возвращена ссылка, хотя полезность этого ограничена несколькими выбранными сценариями).
Неважно, что g()
возвращается, потому что копия всегда создается (по крайней мере, концептуально).