Листинг 9.1. Создание и использование ссылок



1: // Листинг 9.1.

2: // Пример использования ссылок

3:

4: #include <iostream.h>

5:

6: int main()

7: {

8: int intOne;

9: int &rSomeRef = intOne;

10:

11: intOne = 5;

12: cout << "intOne: " << intOne << endl;

13: cout << "rSomeRef: " << rSomeRef << endl;

14:

15: rSomeRef = 7;

16: cout << "intOne: " << intOne << endl;

17: cout << "rSomeRef: " << rSomeRef << endl;

18: return 0;

19: }

 

Результат:

intOne: 5

rSomeRef: 5

intOne: 7

rSomeRef: 7

 

Анализ: В строке 8 объявляется локальная целочисленная переменная intOne, а в строке 9 — ссылка rSomeRef на некоторое целое значение, инициализируемая адресом переменной intOne. Если объявить ссылку, но не инициализировать ее, будет сгенерирована ошибка компиляции. Ссылки, в отличие от указателя, необходимо инициализировать при объявлении.

В строке 11 переменной intOne присваивается значение 5. В строках 12 и 13 выводятся на экран значения переменной intOne и ссылки rSomeRef - они, конечно же, оказываются одинаковыми.

В строке 15 ссылке rSomeRef присваивается значение 7. Поскольку мы имеем дело со ссылкой, а она является псевдонимом для переменной intOne, то число 7 в действительности присваивается переменной intOne, что и подтверждается выводом на экран в строках 16 и 17.

 

Использование оператора адреса (&) при работе со ссылками

 

Если использовать ссылку для получения адреса, она вернет адрес своего адресата. В этом и состоит природа ссылок. Они являются псевдонимами для своих адресатов. Именно это свойство и демонстрирует листинг 9.2.

Листинг 9.2. Взятие адреса ссылки

1: // Листинг 9.2.

2: // Пример использования ссылок

3:

4: #include <iostream.h>

5:

6: int main()

7: {

8: int intOne;

9: int &rSomeRef = intOne;

10:

11: intOne = 5;

12: cout << "intOne: " << intOne << endl;

13: cout << "rSomeRef: " << rSomeRef << endl;

14:

15: cout << "&intOne: " << &mtOne << endl;

16: cout << "&rSomeRef: " << &rSomeRef << endl;

17:

18: return 0;

19: }

 

Результат:

intOne: 5

rSomeRef: 5

&intOne: 0x3500

&rSomeRef: 0x3500

 

Примечание: Результаты работы программы на вашем компьютере могут отличаться от приведенных в последних двух строках.

 

Анализ: И вновь-таки ссылка rSomeRef инициализируется адресом переменной intOno. На этот раз выводятся адреса двух переменных, и они оказываются идентичными. В языке C++ не предусмотрено предоставление доступа к адресу самой ссылки, поскольку в этом нет смысла. С таким же успехом для этого можно было бы использовать указатель или другую переменную. Ссылки инициализируются при создании, и они всегда действуют как синонимы для своих адресатов, даже в том случае, когда применяется оператор адреса.

Например, если у вас есть класс с именем City, вы могли бы объявить объект этого класса следующим образом:

City boston;

Затем можно объявить ссылку на некоторый объект класса City и инициализировать ее, используя данный конкретный объект:

City &beanTown = boston;

Существует только один класс City; оба идентификатора ссылаются на один и тот же объект одного и того же класса. Любое действие, которое вы предпримите относительно ссылки beanTown, будет выполнено также и над объектом boston.

Обратите внимание на различие между символом & в строке 9 листинга 9.2, который объявляет ссылку rSomeRef на значение типа int, и символами & в строках 15 и 16, которые возвращают адреса целочисленной переменной intOne и ссылки rSomeRef.

Обычно для ссылки оператор адреса не используется. Мы просто используем ссылку вместо связанной с ней переменной, как показано в строке 13.

Ссылки нельзя переназначать

 

Даже опытных программистов, которые хорошо знают правило о том, что ссылки нельзя переназначать и что они всегда являются псевдонимами для своих адресатов, может ввести в заблуждение происходящее при попытке переназначить ссылку. То, что кажется переназначением, оказывается присвоением нового значения адресату. Этот факт иллюстрируется в листинге 9.3.

Листинг 9.3. Присвоение значения ссылке

1: // Листинг 9.3

2: // Присвоение значения ссылке

3:

4: #include <iostream.h>

5:

6: int main()

7: {

8: int intOne;

9: int &rSomeRef = intOne;

10:

11: intOne: 5

12: cout << "intOne:\t" << intOne << endl;

13: cout << "rSomeRef:\t" << rSomeRef << endl;

14: cout << "&intOne:\t" << &intOne << endl;

15: cout << "&rSomeRef:\t" << &rSomeRef << endl;

16:

17: int intTwo = 8;

18: rSomeRef = intTwo; // не то что вы думаете

19: cout << "\nintOne:\t" << intOne << endl;

20: cout << "intTwo:\t" << intTwo << endl;

21: cout << "rSomeRef:\t" << rSomeRef << endl;

22: cout << "&intOne:\t" << &intOne << endl;

23: cout << "&intTwo:\t" << &intTwo << endl;

24: cout << "&rSomeRef:\t" << &rSomeRef << endl;

25: return 0;

26: }

 

Результат:

intOne: 5

rSomeRef: 5

&intOne: 0x213e

&rSomeRef: 0x213e

intOne: 8

int:Two: 8

rSomeRef: 8

&intOne: 0x213e

&intTwo: 0x2130

&rSomeRef: 0x213e

 

Анализ: Вновь в строках 8 и 9 объявляются целочисленная переменная и ссылка на целое значение. В строке 11 целочисленной переменной присваивается значение 5, а в строках 12-15 выводятся значения переменной и ссылки, а также их адреса.

В строке 17 создается новая переменная intTwo, которая тут же инициализируется значением 8. В строке 18 программист пытается переназначить ссылку rSomeRef так, чтобы она стала псевдонимом переменной intTwo, но этого не происходит. На самом же деле ссылка rSomeRef продолжает действовать как псевдоним переменной intOne, поэтому такое присвоение эквивалентно следующей операции:

intOne = intTwo;

Это кажется достаточно убедительным, особенно при выводе на экран значений переменной intOne и ссылки rSomeRef (строки 19— 21): их значения совпадают со значением переменной intTwo. На самом деле при выводе на экран адресов в строках 22—24 вы видите, что ссылка rSomeRef продолжает ссылаться на переменную intOne, а не на переменную intTwo.

 

Не рекомендуется: Не пытайтесь переназначить ссылку. Не путайте оператор адреса с оператором ссылки.

Рекомендуется: Используйте ссылки для создания псевдонимов объектов. Инициализируйте ссылки при объявлении.

 

 

На что можно ссылаться

 

Ссылаться можно на любой объект, включая нестандартные (определенные пользователем) объекты. Обратите внимание, что ссылка создается на объект, а не на класс. Нельзя объявить ссылку таким образом:

int & rIntRef = int; // неверно

Ссылку rIntRef нужно инициализировать, используя конкретную целочисленную переменную, например:

int howBig = 200: int & rIntRef = howBig;

Точно так же нельзя инициализировать ссылку классом CAT:

CAT & rCatRef = CAT; // неверно

Ссылку rCatRef нужно инициализировать, используя конкретный объект класса CAT:

CAT frisky;

CAT & rCatRef = frisky;

Ссылки на объекты используются точно так же, как сами объекты. Доступ к данным-членам и методам осуществляется с помощью обычного оператора доступа к членам класса (.), и, подобно встроенным типам, ссылка действует как псевдоним для объекта. Этот факт иллюстрируется в листинге 9.4.


Дата добавления: 2019-02-12; просмотров: 255; Мы поможем в написании вашей работы!

Поделиться с друзьями:






Мы поможем в написании ваших работ!