14.2  Ссылки

В языке С++ введен новый тип данных, родственный указателю – это ссылка (reference). Ссылка – это псевдоним для другой переменной. Ссылка позволяет определить альтернативное имя переменной. Формат объявления ссылки:

тип & идентификатор1 =  идентификатор2;

Такое объявление фактически означает, что переменной с именем "идентификатор2" назначается второе имя "идентификатор1". Ссылка, при объявлении всегда должна быть проинициализирована, и затем ее уже нельзя изменить. Например:

int а, b;

int &alt = а;            // alt является ссылкой на а

alt = b;                     // а = b;    

alt++;                      // а++;

Объявление ссылки напоминает объявление указателя, только вместо * используется &.

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

Ссылки в языке C++  отличаются от указателей следующими особенностями:

· после создания ссылки ее нельзя переделать в ссылку на другой объект; в таких случаях говорят, ссылка не может быть переопределена;

· нельзя создать ссылку на ссылку; каждое упоминание ссылки осуществляет доступ напрямую на объект, на который она ссылается;

· с ссылкой не могут выполняться ни какие-либо арифметические вычисления, ни приведение типов, ни любые другие операции, кроме копирования их связанных значений в другие ссылки;

· ссылки не могут принимать null-значения, тогда как указатели – могут; каждая ссылка ссылается на некий объект, вне зависимости от его корректности;

· ссылка должна быть инициализирована сразу после создания. В частности, локальные и глобальные переменные должны быть проинициализированы там же, где они определены, а ссылки, которые являются данными-членами класса, должны быть инициализированы в списке инициализатора конструктора класса;

· нельзя получить адрес ссылки. Нельзя создавать массивы ссылок и ссылаться на битовое поле. Ссылка должна быть инициализирована до того, как стать членом класса, возвратить значение функции или стать параметром функции.

Существует простое преобразование между указателями и ссылками: операция взятия адреса (&) получает указатель, ссылающийся на тот же самый объект при переходе по ссылке, а ссылка, которая инициализирована при разыменовании (*) указателя будет указывать на тот же объект, что и указатель, где это возможно без неопределенного поведения. Эта тождественность – отражение типичной реализации, которая весьма эффективно превращает ссылки в указатели, которые неявно разыменовываются при каждом использовании.

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

1) если они ссылаются на объект с автоматическим размещением в памяти, который выходит за границы видимости;

2) если они ссылаются на объект, находящийся в блоке динамической памяти, который был освобожден.

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