Ссылки

Язык C++ / Ссылки

В С++ введен новый тип данных – ссылка. Ссылка позволяет определять альтернативное имя переменной.

Формат объявления ссылки:

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

Такое объявление назначает переменной с именем идентификатор2 второе имя идентификатор.

Ссылка при объявлении всегда должна быть проинициализирована!

int a,b;
int &alt=a;   // alt — другое имя переменной а (ссылка на a)
alt = b;  // a=b;
alt++;  // a++;

Если объявлен указатель

int *ptr = &a;

то истины следующие выражения:

*ptr == alt;   // истина, сравниваются значения
ptr == &alt;  // истина, сравниваются адреса

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

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

Возможно инициализировать ссылка на константу:

const char &new_line='\n';

В этом случае компилятор создает некоторую временную переменную temp и ссылку на нее:

char temp = '\n';
const char &new_line = temp;

Основной причиной введения в С++ нового типа данных – ссылки явилась необходимость передачи параметров в функцию через ссылку и получение возвращаемого значения в виде ссылки. Это используется в двух случаях:

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

В обоих случаях можно использовать указатели, но это влечет за собой дополнительные расходы:

  • во-первых, в функции для данного параметра надо выполнять операцию разыменования,
  • во-вторых, при вызове функции надо передавать не саму переменную, а ее адрес.

Пример. Функция, меняющая местами два целых числа:

Без использования ссылок С использованием ссылок
void swap (int *a, int *b)
{
int temp = *a;
*a = *b;
*b = temp;
}
void swap (int &a, int &b)
{
int temp = a;
a = b;
b = temp;
}
Вызов:

int x = 10;
int y = 5;
swap(&x, &y);
Вызов:

int x = 10;
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; возвращать адрес локальной переменной.
  • если возвращаемое значение — ссылка, то нельзя оператором  return возвращать локальную переменную. (Так как после выхода из функции переменная не существует, и мы получим повисшую ссылку).

Чаще всего потребность в ссылках возникает при перегрузке операций.

Назад


Назад: Язык C++

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *