Ссылки : использование нескольких имён объекта

Ссылки

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

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

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

тип &идентификатор = идентификатор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;

Передача параметров функции через ссылку

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

Это используется в двух случаях:

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

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

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

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

Без использования ссылок

1
2
3
4
5
6
void swap (int *a, int *b)
{
  int temp = *a;
  *a = *b;
  *b = temp;
}

Вызов

1
2
3
int x = 10;
int y = 5;
swap(&x, &y);

С использованием ссылок

1
2
3
4
5
6
void swap (int &a, int &b)
{
  int temp = a;
  a = b;
  b = temp;
}

Вызов

1
2
3
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 возвращать локальную переменную. (Так как после выхода из функции переменная не существует, и мы получим повисшую ссылку).

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

Оставьте комментарий

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

Прокрутить вверх