В С++ введен новый тип данных – ссылка.
Ссылка позволяет определять альтернативное имя переменной.
Формат объявления ссылки:
тип &идентификатор = идентификатор2;
Такое объявление назначает переменной с именем идентификатор2 второе имя идентификатор.
Ссылка при объявлении всегда должна быть проинициализирована!
int &alt=a; // alt — другое имя переменной а (ссылка на a)
alt = b; // a=b;
alt++; // a++;
Если объявлен указатель
то истины следующие выражения:
ptr == &alt; // истина, сравниваются адреса
Ссылку можно рассматривать как постоянный указатель, который всегда разыменован, для него не надо выполнять операцию косвенной адресации *.
Ссылка не создает копии объекта, а является лишь другим именем объекта.
Возможно инициализировать ссылка на константу:
В этом случае компилятор создает некоторую временную переменную temp и ссылку на нее:
const char &new_line = temp;
Передача параметров функции через ссылку
Основной причиной введения в С++ нового типа данных – ссылки явилась необходимость передачи параметров в функцию через ссылку и получение возвращаемого значения в виде ссылки.
Это используется в двух случаях:
- для передачи в функцию больших структур, чтобы избежать копирования аргументов в стек;
- для передачи функции аргументов, которые должны быть изменены самой функцией.
В обоих случаях можно использовать указатели, но это влечет за собой дополнительные расходы:
- во-первых, в функции для данного параметра надо выполнять операцию разыменования,
- во-вторых, при вызове функции надо передавать не саму переменную, а ее адрес.
Пример. Функция, меняющая местами два целых числа:
Без использования ссылок
2
3
4
5
6
{
int temp = *a;
*a = *b;
*b = temp;
}
Вызов
2
3
int y = 5;
swap(&x, &y);
С использованием ссылок
2
3
4
5
6
{
int temp = a;
a = b;
b = temp;
}
Вызов
2
3
int y = 5;
swap(x, y);
При использовании ссылок в качестве параметров, наряду с указанными преимуществами есть два существенных недостатка:
Фактический аргумент, переданный в функцию по ссылке, может быть изменен функцией без ведома вызывающей программы. Чтобы этого избежать, параметры, которые не должны изменяться, должны определяться с ключевым словом const. При попытке изменить параметр, объявленный как const будет сообщение об ошибке.
Если при вызове функции происходит несоответствие типов фактических и формальных параметров, С++ выполняет преобразование типа, но для ссылок преобразование типа выполняется через создание промежуточной переменной.
void swap (int &, int &);
int main()
{
int x=10;
unsigned int y;
y=5;
swap(x, y);
…
}Компилятор будет выполнять следующие преобразования:
int temp = (int)y;
int &t = temp;
swap(x, t);В результате swap() поменяет местами значения x и temp.
После выхода из функции переменная temp удалится, а y останется неизменной.
В С++ функции могут не только принимать ссылку в качестве аргумента, но и возвращать ссылку на переменную. Выражение вызова такой функции может появиться в любой части операции присваивания.
Однако если возвращаемое значение — ссылка, то нельзя оператором return возвращать локальную переменную. (Так как после выхода из функции переменная не существует, и мы получим повисшую ссылку).
Чаще всего потребность в ссылках возникает при перегрузке операций.