Шаг 47.
Общие сведения о ссылках

    С этого шага мы начнем рассматривать другой механизм передачи параметров, в частности, с использованием ссылок.

    Использование указателей в качестве альтернативного способа доступа к переменным таит в себе опасность - если был изменен адрес, хранящийся в указателе, то этот указатель больше не ссылается на нужное значение.

    C++ предлагает альтернативу для более безопасного доступа к переменным через указатели. Объявив ссылочную переменную, можно создать объект, который, как указатель, ссылается на другое значение, но, в отличие от указателя, постоянно привязан к этому значению. Таким образом, ссылка на значение всегда ссылается на это значение.

    Ссылку можно объявить следующим образом:

     <имя типа>& <имя ссылки> = <выражение>;
                или
     <имя типа>& <имя ссылки>(<выражение>);

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

#include <iostream.h>
void main()
{
   int ivar = 1234;   //Переменной присвоено значение.
   int *iptr = &ivar; //Указателю присвоен адрес ivar.
   int &iref = ivar;  //Ссылка ассоциирована с ivar.
   int *p = &iref;    //Указателю присвоен адрес iref.

   cout << "ivar = " << ivar << endl;
   cout << "*iptr = " << *iptr << endl;
   cout << "iref = " << iref << endl;
   cout << "*p = " << *p << endl;
}
Текст этой программы можно взять здесь.

    Результат работы программы:

   ivar = 1234
   *iptr = 1234
   iref = 1234
   *p = 1234

    Комментарии к программе. Здесь объявляются четыре переменные. Переменная ivar инициализирована значением 1234. Указателю на целое *iptr присвоен адрес ivar. Переменная iref объявлена как ссылочная. Эта переменная в качестве своего значения принимает адрес расположения в памяти переменной ivar. Оператор:

   cout << "iref = " << iref << endl;

выводит на экран значение переменной ivar. Это объясняется тем, что iref - ссылка на местоположение ivar в памяти.

    Последнее объявление int *p = &iref; создает еще один указатель, которому присваивается адрес, хранящийся в iref. Строки:

   int *iptr = &ivar; 
          и
   int *p = &iref;    

дают одинаковый результат. В них создаются указатели, ссылающиеся на ivar. На рис.1 проиллюстрирована взаимосвязь переменных из приведенной программы:


Рис.1. Взаимосвязь переменных

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

  a) int iv = 3;        b) iref++;     c) iref = 4321;
     iref = iv;
приведут к изменению переменной ivar!


    Замечания.
1. В отличие от указателей, которые могут быть объявлены неинициализированными или установлены в нуль (NULL), ссылки всегда ссылаются на объект. Для ссылок не существует аналога нулевого указателя.
2. Ссылки нельзя инициализировать в следующих случаях: 3. Не существует операторов, непосредственно производящих действия над ссылками!



    На следующем шаге мы перейдем непосредственно к рассмотрению передачи нескольких значений с помощью ссылок.


Предыдущий шаг Содержание Следующий шаг