Ссылочный тип данных
Ссылочный тип (ссылки) иногда называют псевдонимом или синонимом, и служат он для присвоения объекту дополнительного имени. Ссылку можно рассматривать как константный указатель. Ссылка связывается с конкретным объектом в момент ее создания и в дальнейшем не может быть изменена, т.е. не может быть перенаправлена на другой объект, подобно обычному указателю. Ссылка позволяет косвенно манипулировать объектом, точно так же, как это делается с помощью указателя. Однако эта косвенная манипуляция не требует специального синтаксиса (операции разыменования «*»), необходимого для указателей. Подводя итог вышесказанному, можно отметить, что ссылку можно рассматривать как альтернативное имя объекта, а также как безопасный вариант указателя. Ссылки имеют три особенности, отличающие их от указателей: - при объявлении ссылка обязательно инициализируется, т.е. должна быть направлена на уже существующий объект, - ссылка всегда указывает на один и тот же объект, - при обращении к объекту по ссылке не требуется указывать операцию разыменования (*), т.к. он выполняется автоматически. Создание ссылки похоже на создание обычной переменной – тип, имя, инициализатор. Но справа от типа надо поставить символ &. Пример 15. int i; //целая переменная int &ref = i; //определение ссылки на переменную i int &ref1; //ошибка, ссылка должна быть инициализирована
После этого можно пользоваться ссылкой ref так же, как самой переменной i: i=8; //”прямой” доступ к i ref = 8; // “косвенный” доступ к i через ссылку
При работе со ссылками необходимо учитывать следующее: - ссылка не может существовать сама по себе – она обязательно связана с какой-либо переменной, - у ссылки нет своего адреса – если взять адрес ссылки, то получим адрес связанной с ней переменной, - все, что мы можем сделать со ссылкой – это создать ее. Ссылку нельзя уничтожить или перенаправить на другую переменную. Она уничтожается автоматически при выходе из блока, в котором была объявлена. Все операции со ссылками реально воздействуют на адресуемые ими объекты. В том числе и операция взятия адреса. Пример 16. … int val = 1024; int &refVal = val; //ссылка на val refVal+=2; //val=val+2 int ii= refVal; //ii=val //устанавливает указатель pi на переменную val int *pi=&refVal; … Если несколько ссылок определяются в одной инструкции через запятую, перед каждой ссылкой должен стоять & int &rval=val1, &rval2=val2; Если указателю присвоить нулевое значение, это означает, что указатель не установлен (не указывает ни на один объект), если же нулевое значение присвоить ссылке, это будет означать, что ссылка связана с переменной, значение которой равно 0. Пример 17. … int *pi=0; //pi не указывает ни на какой объект const int &ri=0;
означает примерно следующее:
int temp=0; const int &ri = temp; Что касается операции присваивания, то работа с указателями тоже отличается от аналогичной работы со ссылками. Пример 18. //работа с указателями //определение переменных val1 и val2 … int val1=1024, val2=2048; //установка указателей int *pi1=&val1, *pi2=&val2; pi1=pi2; … Переменная val1, на которую указывает pi1, остается неизменной, а указатель pi1 получает значение адреса переменной val2. Таким образом, pi1 и pi2 теперь указывают на один и тот же объект val2. Проделаем подобные операции со ссылками. … int &ri1=val1, &ri2=val2; //создание ссылок ri1 и ri2 ri1=ri2; … Операция присваивания ri1=ri2 меняет саму переменную val1 (записывает в нее значение из val2), но ссылка ri1 по-прежнему адресует val1. Пример наглядно показывает, что с точки зрения синтаксиса работа со ссылкой ничем не отличается от работы с переменной, на которую она ссылается. Следует отметить, что механизм ссылок отсутствует в классическом С, но все современные компиляторы С++ поддерживают ссылки. Ссылки редко используются как самостоятельные объекты, обычно они употребляются в качестве формальных параметров и возвращаемых значений функций.
|