Читаем Освой самостоятельно С++ за 21 день. полностью

13:   cout << "Main. After swap, x: " << x << " у: " << у << "\n";

14:   return 0;

15: }

16:

17: void swap (int *px, int *py)

18: {

19:    int temp;

20:

21:    cout << "Swap. Before swap, *рх: " << *px << " *py: " << *py << "\n";

22:

23:    temp = *px;

24:    *px = *py;

25:    *py = temp;

26:

27:    cout << "Swap. After swap, *px: " << *px << " *py: " << *py << "\n";

28:

29: }


Результат:

Main. Before swap, x: 5 y: 10

Swap. Before swap, *px: 5 *py: 10

Swap. After swap, *px: 10 *py: 5

Main. After swap, x: 10 y: 5


Анализ: Получилось! В строке 5 изменен прототип функции swap где в качестве параметров объявляются указатели на значения типа int, а не сами переменные типа int. При вызове в строке 12 функции swap в качестве параметров передаются адреса переменных x и у.

В строке 19 объявляется локальная для функции swap переменная temp, которой вовсе не обязательно быть указателем: она будет просто хранить значение *px (т.е. значение переменной x в вызывающей функции) в течение жизни функции. После окончания работы функции переменная temp больше не нужна.

В строке 23 переменной temp присваивается значение, хранящееся по адресу px. В строке 24 значение, хранящееся по адресу px, записывается в ячейку с адресом py. В строке 25 значение, оставленное на время в переменной temp (т.е. исходное значение, хранящееся по адресу px), помещается в ячейку с адресом py.

В результате значения переменных вызывающей функции, адреса которых были переданы функции swap, успешно поменялись местами.


Передача ссылок в функцию swap

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

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

Листинг 9.7. Та же фцнкция swap, но с использованием ссылок 

1: // Листинг 9.7. Пример передачи аргументов как

2: // ссылок с помощью ссылок!

3:

4: #include

5:

6: void swap(int &x, int &y);

7:

8: int main

9: {

10:   int x = 5, у = 10;

11:

12:   cout << "Main. Before swap, x: " << x << " у: " << у << "\n";

13:   swap(x,у);

14:   cout << "Main. After swap, x: " << x << " у: " << у << "\n";

15:   return 0;

16: }

17:

18: void swap(int ℞, int &ry)

19: {

20:    int temp;

21:

22:    cout << "Swap. Before swap, rx: " << rx << " ry: " << ry << "\n";

23:

24:    temp = rx;

25:    rx = ry;

26:    ry = temp;

27:

28:    cout << "Swap. After swap, rx: " << rx << " ry: " << ry << "\n";

29:

30: }


Результат:

Main. Before swap, x:5 y: 10

Swap. Before swap, rx:5 ry:10

Swap. After swap, rx:10 ry:5

Main. After swap, x:10, y:5


Анализ: Точно так же, как и в примере с указателями, в строке 10 объявляются две переменные, а их значения выводятся на экран в строке 12. В строке 13 вызывается функция swap, но обратите внимание на то, что ей передаются именно значения x и у, а не их адреса. Вызывающая функция просто передает свои переменные.

После вызова функции swap выполнение программы переходит к строке 18, в которой эти переменные идентифицируются как ссылки. Их значения выводятся на экран в строке 22, но заметьте, что для этого не требуется никаких специальных операторов, поскольку мы имеем дело с псевдонимами для исходных значений и используем их в этом качестве.

В строках 24—26 выполняется обмен значений, после чего они выводятся на экран в строке 28. Управление программой вновь возвращается в вызывающую функцию, и в строке 14 эти значения опять выводятся на экран, но уже в функции main. Поскольку параметры для функции swap объявлены как ссылки, то и переменные из функции main передаются как ссылки, следовательно, они также изменяются и в функции main.

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

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

Перейти на страницу:

Похожие книги

Сущность технологии СОМ. Библиотека программиста
Сущность технологии СОМ. Библиотека программиста

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

Дональд Бокс

Программирование, программы, базы данных / Программирование / Книги по IT