В языке С++ введен новый тип данных, родственный указателю – это ссылка (reference). Ссылка – это псевдоним для другой переменной. Ссылка позволяет определить альтернативное имя переменной. Формат объявления ссылки:
тип & идентификатор1 = идентификатор2;
Такое объявление фактически означает, что переменной с именем "идентификатор2" назначается второе имя "идентификатор1". Ссылка, при объявлении всегда должна быть проинициализирована, и затем ее уже нельзя изменить. Например:
int а, b;
int &alt = а; // alt является ссылкой на а
alt = b; // а = b;
alt++; // а++;
Объявление ссылки напоминает объявление указателя, только вместо * используется &.
Ссылка является скрытым указателем и во всех случаях, и для любых целей её можно употреблять просто как еще одно имя переменной. Ссылку допустимо использовать тремя способами. Во-первых, ссылку можно передавать в функцию. Во-вторых, ссылку можно возвратить из функции. Наконец, можно создать независимую ссылку, как это показано было выше.
Ссылки в языке C++ отличаются от указателей следующими особенностями:
· после создания ссылки ее нельзя переделать в ссылку на другой объект; в таких случаях говорят, ссылка не может быть переопределена;
· нельзя создать ссылку на ссылку; каждое упоминание ссылки осуществляет доступ напрямую на объект, на который она ссылается;
· с ссылкой не могут выполняться ни какие-либо арифметические вычисления, ни приведение типов, ни любые другие операции, кроме копирования их связанных значений в другие ссылки;
· ссылки не могут принимать null-значения, тогда как указатели – могут; каждая ссылка ссылается на некий объект, вне зависимости от его корректности;
· ссылка должна быть инициализирована сразу после создания. В частности, локальные и глобальные переменные должны быть проинициализированы там же, где они определены, а ссылки, которые являются данными-членами класса, должны быть инициализированы в списке инициализатора конструктора класса;
· нельзя получить адрес ссылки. Нельзя создавать массивы ссылок и ссылаться на битовое поле. Ссылка должна быть инициализирована до того, как стать членом класса, возвратить значение функции или стать параметром функции.
Существует простое преобразование между указателями и ссылками: операция взятия адреса (&) получает указатель, ссылающийся на тот же самый объект при переходе по ссылке, а ссылка, которая инициализирована при разыменовании (*) указателя будет указывать на тот же объект, что и указатель, где это возможно без неопределенного поведения. Эта тождественность – отражение типичной реализации, которая весьма эффективно превращает ссылки в указатели, которые неявно разыменовываются при каждом использовании.
Кроме того, из-за ограничения операций над ссылками они намного легче в понимании, чем указатели, а также более защищены от ошибок. Ссылки могут стать некорректными лишь в двух случаях:
1) если они ссылаются на объект с автоматическим размещением в памяти, который выходит за границы видимости;
2) если они ссылаются на объект, находящийся в блоке динамической памяти, который был освобожден.
В первом случае некорректные ссылки легко обнаруживаются автоматически, если они имеют статическую область видимости, но возникают проблемы, если ссылки указывают на динамически размещенные объекты. Во втором случае некорректные ссылки обнаружить сложнее.