Тема 2. Ссылки как тип данных 


Мы поможем в написании ваших работ!



ЗНАЕТЕ ЛИ ВЫ?

Тема 2. Ссылки как тип данных



 

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

Для определения ссылки используется символ &, если он употребляется в таком контексте:

type & имя_ссылки инициализатор;

В качестве инициализатора, наличие которого обязательно, должно выступать имеющее значение леводопустимое выражение, то есть имя некоторого объекта, имеющего место в памяти. Значением ссылки после определения с инициализацией становится адрес этого объекта. Например: int k=2; int & ref=k; В определении ссылки символ ‘&’ не является частью типа, то есть ref имеет тип int и именно так должна восприниматься в программе.

Функционально ссылка ведет себя подобно обычной переменной того же, что и ссылка, типа. Для доступа к содержимому участка памяти, на который «смотрит» ссылка, нет необходимости явно выполнять разыменование, как это нужно для указателя.

Ссылки не есть полноправные объекты, подобные переменным, либо указателям. После инициализации значение ссылки изменить нельзя, она всегда «смотрит» на тот участок памяти(на тот объект), с которым она связана инициализацией. Ни одна из операций не действует на ссылку, а относится к тому объекту, с которым она связана. Можно считать, что это основное свойство ссылки. Таким образом, ссылка полностью аналогична (идентична) исходному имени объекта.

Пусть определены:

int ar[]={1,2,3,4}; //ar - массив

int *p=ar; //р - указатель

int & ref=ar[0]; //ref – ссылка на первый элемент массива

int *& rp=ar; //ссылка на указатель(на имя массива)

 

Для ссылок и указателей из приведенного примера соблюдаются равенства:

p= =&ref, *p= =ref, rp= =ar; ref= = ar[0].

Результатом применения операции sizeof к ссылке является не ее размер, а размер именуемого ею объекта.

Так как ссылки не есть настоящие объекты, то существуют ограничения при определении и использовании ссылок. Во-первых, ссылка не может иметь тип void. Ссылку нельзя создать с помощью операции new, то есть для ссылки нельзя выделить новый участок памяти. Не определены ссылки на другие ссылки. Нет указателей на ссылки и невозможно создать массив ссылок.

Хотя значение ссылки не может измениться, однако один объект может быть адресован любым числом ссылок и указателей:

int k=7; //определена переменная k

int & r1=k; //ссылка r1 связана с k

int * p=&r1; //указатель p адресует k

int & r2=r1; //ссылка r2 указывает на k

 

Теперь к значению переменной k можно добраться четырьмя способами: с помощью имени k; ссылки r1; разыменования указателя *p и ссылки r2.

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

int k=5;

const int & ref=k; //ref – ссылка на константу

При таких определениях:

k=0; //допустимый оператор присваивания

ref=0; //ошибка, так как ссылка объявлена на константу

При определении ссылок обязательна их инициализация! Однако в описаниях ссылок инициализация присутствовать не обязана, однако она не запрещена.

К таким описаниям ссылок относятся:

  • описания внешних ссылок(со спецификатором extern);
  • описания ссылок на компоненты класса;
  • спецификации формальных параметров функций;
  • описание типа возвращаемого функцией значения.

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

Пусть, например:

int f1(int & k) // функция возвращает целое число

{ return k;}

int & f2(int & k) //функция возвращает ссылку на переменную k

{ return k;}

Обе функции возвращают числовое значение, совпадающее с числовым значением входного параметра k. Для второго варианта возможна следующая конструкция вызова:

int main (void)

{ int n=3;

f2(n)=7; // n станет равным семи

return 0;

}

Подобно указателю на функцию определяется и ссылка на функцию по формату: тип_функции(&имя_ссылки)(спецификация_параметров_функции)=инициализирующее выражение;

Например,

int func(float, int); //прототип функции

int (&ref) (float, int)=func; //определение ссылки

Использование имени функции без скобок (и без параметров) воспринимается как адрес функции.

Ссылка на функцию обладает всеми правами основного имени функции, то есть является его синонимом (псевдонимом). Изменить значение ссылки на функцию (ссылка на указатель) невозможно, поэтому указатели на функции имеют гораздо большую сферу применения, чем ссылки.

Следующая программа иллюстрирует вызовы функции по основному имени, по указателю и по ссылке:

#include < iostream. h>

void func(char lit)

{ cout << endl <<lit;}

int main (void)

{ void (*pf)(char); //pf – указатель на функцию

void (&ref)(char)=func; //ref –ссылка на функцию

func(‘A’); //вызов по имени

pf=func; //указателю присваивается адрес функции

(*pf)(‘B’); //вызов по адресу с помощью указателя

ref(‘C’); //вызов функции по ссылке

return 0;

}

 

Возвращение функцией ссылки позволяет организовать многократное вложенное обращение к нескольким функциям. В результате таких вложенных обращений один и тот же объект можно многократно изменять по разным законам.

 

Основная литература – 5[гл. 6,215-227],[гл.4, 127-142]

Контрольные вопросы:

  1. Что такое ссылка? Приведите две важных области применения ссылок.
  2. Какие достоинства и недостатки параметров-ссылок.
  3. Создается ли копия объекта при передаче его в функцию через ссылку?
  4. Как передается адрес аргумента при использовании параметра-ссылки?
  5. Что такое независимая ссылка?

 



Поделиться:


Последнее изменение этой страницы: 2016-12-13; просмотров: 165; Нарушение авторского права страницы; Мы поможем в написании вашей работы!

infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 3.133.79.70 (0.009 с.)