Выбрать главу

Глава 8: Функции, часть вторая: ссылки, перегрузка и использование аргументов по умолчанию

В этой главе мы продолжим изучение функций, а именно рассмотрим три самые важные темы, связанные с функциями C++: ссылки, перегрузка функций и использование аргументов по умолчанию. Эти три средства в значительной степени расширяют возможности функций. Как будет показано ниже, ссылка — это неявный указатель. Перегрузка функций представляет собой свойство, которое позволяет одну функцию реализовать несколькими способами, причем в каждом случае возможно выполнение отдельной задачи. Поэтому есть все основания считать перегрузку функций одним из путей поддержки полиморфизма в C++. Используя возможность задания аргументов по умолчанию, можно определить значение для параметра, которое будет автоматически применено в случае, если соответствующий аргумент не задан.

Поскольку к параметрам функций часто применяются ссылки (это основная причина их существования), начнем эту главу с краткого рассмотрения способов передачи аргументов функциям.

Два способа передачи аргументов

При вызове по значению функции передается значение аргумента.

Чтобы понять происхождение ссылки, необходимо знать теорию процесса передачи аргументов. В общем случае в языках программирования, как правило, предусматривается два способа, которые позволяют передавать аргументы в подпрограммы (функции, методы, процедуры). Первый называется вызовом по значению (call-by-value). В этом случае значение аргумента копируется в формальный параметр подпрограммы. Следовательно, изменения, внесенные в параметры подпрограммы, не влияют на аргументы, используемые при ее вызове.

При вызове по ссылке функции передается адрес аргумента.

Второй способ передачи аргумента подпрограмме называется вызовом по ссылке (call-by-reference). В этом случае в параметр копируется адрес аргумента (а не его значение). В пределах вызываемой подпрограммы этот адрес используется для доступа к реальному аргументу, заданному при ее вызове. Это значит, что изменения, внесенные в параметр, окажут воздействие на аргумент, используемый при вызове подпрограммы.

Как в C++ реализована передача аргументов

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

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

#include <iostream>

using namespace std;

int sqr_it(int x);

int main()

{

 int t=10;

 cout << sqr_it(t) << ' ' << t;

 return 0;

}

int sqr_it(int x)

{

 x = x*x;

 return x;

}

В этом примере значение аргумента, передаваемого функции sqr_it(), 10, копируется в параметр х. При выполнении присваивания х = х*х изменяется лишь локальная переменная х. Переменная t, используемая при вызове функции sqr_it(), по-прежнему будет иметь значение 10, и на нее никак не повлияют операции, выполняемые в этой функции. Следовательно, после запуска рассматриваемой программы на экране будет выведен такой результат: 100 10.

Узелок на память. По умолчанию функции передается копия аргумента. То, что происходит внутри функции, никак не отражается на значении переменной, используемой при вызове функции.

Использование указателя для обеспечения вызова по ссылке

Несмотря на то что в качестве С++-соглашения о передаче параметров по умолчанию действует вызов по значению, существует возможность "вручную" заменить его вызовом по ссылке. В этом случае функции будет передаваться адрес аргумента (т.е. указатель на аргумент). Это позволит внутреннему коду функции изменить значение аргумента, которое хранится вне функции. Пример такого "дистанционного" управления значениями переменных вы видели в предыдущей главе при рассмотрении возможности вызова функции с указателями (в примере программы функции передавался указатель на целочисленную переменную). Как вы знаете, указатели передаются функциям подобно значениям любого другого типа. Безусловно, для этого необходимо объявить параметры с типом указателей.