Здавалка
Главная | Обратная связь

Ссылки в качестве переменных



В программе (листинг 1.15) приводятся четыре способа адреса­ции и вывода целого значения.

Листинг 1.15. REFVAR.CPP (демонстрация ссылочных переменных)

1:#include <iostream.h>

2:

Main()

4: {

5: int ivar = 1234;

// Переменной присвоено значение

6: int *iptr = &ivar;

// Указателю присвоен адрес ivar

7: int &iref = ivar;

// Ссылка ассоциирована с ivar

8: int *p = &iref;

// Указателю присвоен адрес iref

9:

10: cout « "ivar == " « ivar « '\n';

11: cout « "*iptr == " « *iptr « '\n';

12: cout « "iref == " « iref « '\n';

13: cout « "*p == " << *p « '\n';

14: return 0;

15:}


 

В строках 5-8 объявляются четыре переменные. Первая — простое целое ivar, инициализированное значением 1234. Следующая, — указатель на целое с именем iptr, которой присвоен адрес ivar. Третья объяв­лена как ссылочная переменная. Строка

int &iref = ivar;

объявляет iref как ссылку на целое значение. Что касается iref, то ей присваивается ivar не как значение пере­менной, а как адрес в памяти. Следуя объявлению, iref указывает на ivar подобно указателю. Как показано в строке 12, оператор

cout « "iref == " « iref « '\n';

выводит значение ivar — 1234. Это происходит благодаря использованию iref в качестве ссылки на местополо­жение переменной ivar в памяти.

Четвертое объявление в строке 8 создает еще один указатель — p, которому присваивается адрес, храня­щийся в iref. Строки 6 и 8 дают одинаковый результат. В обеих строках создаются указатели, ссылающиеся на ivar. Как показано в строке 13, употребление указателя в выражении *p дает доступ к значению ivar. На рис. 1.2 проиллюстрирована взаимосвязь переменных из листинга 1.15. Как видно из иллюстрации, исполь­зование iref очень похоже на использование разыменования указателя *p. В обоих выражениях осуществляет­ся доступ к значению ivar — 1234.

Рис. 1.2. Взаимосвязь переменных в листинге 1.15, REFVALCPP

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

 

В REFVAL.CPP вы не можете объявить новую целочисленную переменную и при­своить ее адрес iref:

int anotherInt;

iref = anotherInt; // ???

Это присваивание не заставит iref ссылаться на anotherInt. Это выражение присвоит значение anotherInt объекту, на который iref ссылается, другими словами — ivar. Так же вы можете присваивать новые значения объекту, к которому относится ссылка. Например, выражение

iref = 4321;

присвоит ivar значение 4321. Эти правила будет легче запомнить, если представить себе ссылки как неизме­няемые альтернативные имена, похожие на указатели (но не идентичные им!).

Как следует из вышесказанного, ссылки должны быть инициализированы при их объявлении. Строка 7, к примеру, не может быть написана как

int &iref; // ???

 

В отличие от указателей, которые могут быть объявлены в неинициализированном состоянии или установ­лены в нуль (если указатель не ссылается на необходимые данные), ссылки всегда ссылаются на объект. Для ссылок не существует аналога нулевого указателя.

Ссылки нельзя инициализировать значениями в следующих четырех особых случаях: при их объявлении с ключевым словом ехtеrn, при использовании в качестве параметров функции, при использовании в качестве типа возвращаемого значения функции или в объявлениях классов.

 

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

 

Добавьте между строками 13 и 14 листинга 12.15 следующий оператор:

iref++;

Компилятор сгенерирует код, инкрементирующий ivar — переменную, на которую ссылается iref. Оператор не совершит никаких действий непосредственно над iref.

 

Ссылки также могут ссылаться на константы.

 

Разумеется, вы не можете присвоить значение непосредст­венно ссылке. Объявление

int &iref = 1234; // ???

вызовет сообщение об ошибке при компиляции, поскольку 1234 не является объектом, на который iref сможет сослаться. Вы можете, конечно, объявить константную ссылку на допустимый объект следующим образом:

int x = 1234; // Объявление и инициализация целочисленного объекта

const int &iref = x; // Объявление iref как константной ссылки на x

Этот прием очень полезен, поскольку эффективно превращает переменную в константу, которую нельзя подвергнуть изменениям. Например, вы можете записать значение x в выходной поток с помощью ссылки сле­дующим образом:

cout << "iref = " << iref << '\n'; // Все в порядке

Вы также можете изменить значение переменной x:

x = 4321; // Тоже годится

Поскольку iref — константа, то вы, конечно, не сможете присвоить новое значение x через ссылку:

iref = 4321; // ??? Нельзя

Попытка скомпилировать последнее выражение приведет к выдаче сообщения об ошибке "Cannot modify a const object in function main()" (Нельзя изменить константный объект в функции main()).







©2015 arhivinfo.ru Все права принадлежат авторам размещенных материалов.