Глава 11. Функции________________________________________249
// Расчет числа Пи с точностью precision.
// Таким образом, если precision = 10, то число Пи
// будет рассчитано с точностью до 10-го знака после запятой
return pi;
Заметьте, что за ключевым словом return следует переменная, чей тип совпадает с возвращаемым типом. В качестве возвращаемых могут быть любые типы, в том числе не упомянутые здесь базовые (например, long double) и определенные пользователем.
В рассмотренном случае имел место возврат по значению (return by value). Функция pi возвращает то, что и следовало ожидать — значение, присвоенное переменной pi. По значению можно возвращать и более сложные величины, в том числе структуры и классы, но это, как правило, обходится недешево.
Замечание
Когда возвращаемый тип — это один из встроенных, которые в большинстве своем умещаются в одном-двух регистрах микропроцессора, то накладные расходы на возврат значения объекта обычно невелики. Сложности возникают при использовании в качестве возвращаемого производного типа, например, класса или структуры.
Поскольку сложные пользовательские типы могут состоять из одного или нескольких элементов других типов, каждый из которых может нуждаться в выделении ресурсов и инициализации, то возврат значения такого объекта, скорее всего, повлечет за собой большие издержки.
Почему это так важно? При возврате по значению вы получаете не сам объект, а значение этого объекта — т. е. его копию. А поскольку это копия, значит, для возврата значения приходится создавать новый объект — это и есть та цена, которую вы платите. При кажущейся незначительности она может сильно сказаться на производительности программы.
Некоторые утверждают, что программы, написанные на C++, чересчур медлительны. На самом деле грамотно реализованные программы на C++ столь же быстры, как и на С (а программы на этом языке одни из самых быстрых), а то и быстрее. Если, конечно, не злоупотреблять возвратом сложных объектов по значению.
Помимо возврата данных по значению возможен также возврат с помощью операций разыменования (*) или получения адреса (&); о синтаксисе возвращаемых типов при использовании этих операций будет рассказано ниже.
Совет
Этот раздел посвящен больше функциям, чем эффектам, возникающим при передаче и возвращении объектов по значению или по ссылке. Не вполне очевидные аспекты передачи объектов по ссылке и по значению детально рассматриваются в главе 17 "Конструкторы: копирование и присваивание".