2016-06-01 2 views
4

Я ищу разъяснение того, что именно происходит, когда вы возвращаете ссылку на объект в функции с возвращаемым типом этого объекта.C++: Возвращение по значению с помощью ссылки

Рассмотрим следующую функцию:

CObject getObject() { 
    CObject localObject; 
    CObject &objectRef(localObject); 
    return objectRef; 
} 

Это мое понимание того, что эта функция возвращает копию «localObject», а не возвращали ссылку на «localObject». Это верно? Является ли это по существу созданием и возвратом нового объекта с localObject в качестве параметра конструктора? Е.Г.,

CObject newObject(localObject); 
+0

Выполнение этого действия в стеке .... делать на куче inst –

+0

делать в куче, если вам нужна куча не только для того, чтобы этот пример работал –

ответ

6

Это вернет копию вашего объекта. Однако будьте осторожны, если вы измените объявление функции, чтобы вернуть ссылку, ваш код приведет к неопределенному поведению.

Пример:

class CObject{ 
    public: 
    CObject(){std::cout << "cosntructing ";} 
    CObject(const CObject& other){std::cout << "copying ";} 
}; 

CObject getObject(){ 
    CObject localObject; 
    CObject &objectRef(localObject); 
    return objectRef; 
} 

int main(){ 
    auto result = getObject(); 
} 

Это приведет:

cosntructing копирование

Примечание: вы не можете получить те же результаты, если ваш компилятор полностью оптимизируя код из-за RVO. Поэтому отключите всю оптимизацию и попробуйте. Как сказал @Caduchon, даже без оптимизации результаты могут измениться из-за копирования.


Пример функции с непредсказуемым поведением:

CObject& getObject() { 
    CObject localObject; 
    CObject &objectRef(localObject); 
    return objectRef; 
} 
+0

Обратите внимание, что копия может быть опущена, если результат присваивается новой переменной. Компилятор может увидеть это и построить непосредственно переменную из функции. – Caduchon

+0

@ Кадухон вы были быстрее меня :) он был отредактирован. Спасибо, что упомянул –

+1

. До тех пор, пока тип возврата по значению, он всегда будет создавать копию объекта, который передается через ссылку. Спасибо за тщательный ответ! – Ludus

1

Вы правы, что он не возвращает ссылку на локальный объект. В терминах того, что на самом деле возвращается, ответ немного более тонкий. Из-за чего-то, называемого return value optimisation, компилятор фактически создаст только один экземпляр CObject в результате вызова функции. Это трюк оптимизации, который в основном означает, что оригинал localObject сконструирован таким образом, чтобы его можно было непосредственно использовать вызывающей функцией - поэтому при возврате вызова не требуется построение копии.

Смежные вопросы