Сравните следующие два фрагмента кода, первый с использованием ссылки на большой объект, а второй имеет большой объект в качестве возвращаемого значения. Акцент на «большой объект» означает тот факт, что повторные копии объекта, без необходимости, являются потраченными впустую циклами.Возвращение больших объектов в функции
Используя ссылку на большой объект:
void getObjData(LargeObj& a)
{
a.reset() ;
a.fillWithData() ;
}
int main()
{
LargeObj a ;
getObjData(a) ;
}
Использование большого объекта в качестве возвращаемого значения:
LargeObj getObjData()
{
LargeObj a ;
a.fillWithData() ;
return a ;
}
int main()
{
LargeObj a = getObjData() ;
}
Первый фрагмент кода не требует копирования больших объектов.
Во втором фрагменте объект создается внутри функции, и, как правило, при возврате объекта требуется копия. В этом случае, однако, в main()
объект объявляется. Будет ли компилятор сначала создать построенный по умолчанию объект, а затем скопировать объект, возвращаемый getObjData()
, или он будет таким же эффективным, как и первый фрагмент?
Я думаю, что второй фрагмент легче читать, но я боюсь, что он менее эффективен.
Редактировать: Как правило, я рассматриваю случаи LargeObj
как универсальные классы контейнеров, которые для аргумента содержат тысячи объектов внутри них. Например,
typedef std::vector<HugeObj> LargeObj ;
так прямо изменения/добавления методов LargeObj
не является непосредственно доступным решением.
Благодарим за отличное объяснение, а также код для «проверки» оптимизации возвращаемого значения. Я могу подтвердить, что компилятор Microsoft Visual Studio 2008 возвращает тот же результат, что и g ++, то есть оптимизированный набор операций. – swongu
Я считаю, что Visual Studio будет включать только RVO в/O2 или выше (например, не в коде отладки, а не только с помощью/O). – Bklyn
Я проверил его с VS2008 и обнаружил, что/Od (отключено) вызывает X :: X() и X :: X (X const &), тогда как/O1/O2/Ox вызывает только X :: X(). Таким образом, при отключенной оптимизации копия выполняется при возврате за пределы f(). – swongu