Сохранить возвращаемое значение функции в ссылке C ++ - PullRequest
23 голосов
/ 12 мая 2010

Допустимо ли хранить возвращаемое значение объекта в ссылке?

class A { ... };
A myFunction()
{
    A myObject;
    return myObject;
} //myObject goes out of scope here

void mySecondFunction()
{
    A& mySecondObject = myFunction();
}

Можно ли сделать это, чтобы избежать копирования myObject в mySecondObject? myObject больше не нужен и должен быть точно таким же, как mySecondObject, поэтому теоретически было бы быстрее просто передать владение объектом от одного объекта другому. (Это также возможно при использовании расширенного общего указателя, но это накладные расходы общего указателя.)

Заранее спасибо.

Ответы [ 3 ]

30 голосов
/ 12 мая 2010

Запрещается привязывать временную ссылку к неконстантной ссылке, но если вы сделаете свою ссылку постоянной, вы продлите время жизни временной ссылки до ссылки, см. этот пост Данни Калева об этом .

Короче говоря:

const A& mySecondObject = myFunction();
7 голосов
/ 12 мая 2010

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

7 голосов
/ 12 мая 2010

Это возможно с константной ссылкой.

myFunction возвращает значение, поэтому возвращаемое значение является временным объектом. Вы можете привязать временную ссылку к константной ссылке, и время жизни временной привязки увеличивается до времени жизни ссылки. Вы не можете привязать временную ссылку к неконстантной ссылке (к сожалению).

Возвращаемое значение myFunction может быть копией из myObject. С положительной стороны, elision конструктора копирования (в данном случае «именованная оптимизация возвращаемого значения») позволяет компилятору создавать myObject непосредственно во временное значение, которое является возвращаемым значением myFunction, предположительно расположенным где-то в стеке вызывающий код. Если это так, то когда myObject выходит из области видимости, объект фактически не уничтожается. Оптимизация обычно реализуется - например, GCC (обычно?) Делает это даже без каких-либо флагов оптимизации.

Copy ctor elision также позволяет компилятору избежать копирования, если вы это сделали:

A mySecondObject = myFunction();

Для этого требуется применение обоих допустимых типов копирования ctor: (1) возврат именованного значения из функции и (2) инициализация объекта из временного.

...