Глава 9
Ссылки обладают почти теми же возможностями что и указатели, но синтаксис их несколько проще.
Вверх
Ссылка-это псевдоним;при создании она инициализируется именем
другого объекта, адресата. С этого момента ссылка выступает
в роли альтернативного имени адресата, и все что делается
с ссылкой, происходит и с объектом.
При объявлении ссылки вначале указывают тип объекта адресата,
за которым следует оператор ссылки (&) и имя ссылки.
Обратите внимание на то что оператор ссылки (&) выглядит
так же , как и оператор возвращения адреса, который используется
при работе с указателями. Но это не один и тот же оператор,
хотя они и очень похожи.
Программа
Создание и использование ссылок
//Listing 9.1
// Demonstrating the use of References
#include <iostream>
int main()
{
intOne = 5;
rSomeRef = 7;
Сначала объявляется локальная целочисленная переменная intOne,
а в следующей строке объявляется ссылка rSomeRef на целое значение,
Если объявить но не инициализировать ссылку, произойдет ошибка компиляции.
Далее переменной присваивается значение 5.
И затем выводится на экран значение переменной и значение ссылки,
cout << "intOne: " << intOne << endl;
конечно они оказываются одинаковыми.
Поскольку это ссылка и она является псевдонимом переменной intOne ,
Вверх
Если запросить ссылку об адресе, то она вернет адрес своего адресата.
В этом и состоит природа ссылок. Они являются псевдонимами для
своих адресатов.
Посмотрим программу:
int main()
{
int intOne;
intOne = 5;
cout << "&intOne: " << &intOne << endl;
return 0;
В первых двух выводах выводится значение равное 5.
Ссылка rSomeRef инициализируется адресом переменной intOne.
Затем переменной присваивается значение
После этого значение переменной выводится на экран, затем
значение ссылки на эту переменную выводится на экран.
Как видим значения одинаковы. Дак ведь это в одном случае переменная,
во втором случае та же переменная но под псевдонимом ссылки.
То есть один и тот же объект, но один раз под именем, второй раз
под псевдонимом:
Далее выводятся адреса двух переменных и они оказываются
идентичными.
В первом случае это адрес переменной, во втором случае адрес этой же
переменной но она под псевдонимом ссылки. Естественно что адрес одного и того
же объекта одинаков, ведь это один объект.
В С++ не предусмотрено предоставление доступа к адресу самой
ссылки, поскольку в этом нет смысла. С таким же успехом для этого
можно использовать указатель или другую переменную.
и символом & в строках 15, 16 , которые возвращают адреса
Обычно для ссылки оператор взятия адреса не используется.
Просто ссылка используется точно так же как и переменная,
вместо которой она применяется.
Вверх
Даже опытных программистов которым хорошо известно что
ссылки нельзя переназначать и что они являются псевдонимами
своих адресатов, может ввести в заблуждение явление, происходящее
при попытке переназначить ссылку. То что кажется переназначением,
оказывается присвоением нового значения адресату.
//Listing 9.3
//Reassigning a reference
int main()
{
int intOne;
intOne = 5;
int intTwo = 8;
cout << "\nintOne:\t" << intOne << endl;
cout << "&intOne:\t" << &intOne << endl;
Результат:
intOne: 8
&intOne: 0x213e
Анализ:
Ссылка rSomeRef инициализируется адресом переменной intOne.
Затем переменной присваивается значение
После этого значение переменной выводится на экран, затем
значение этой же переменной под псевдонимом ссылки выводится на экран.
Затем на экран выводится адрес переменной и адрес этой же переменной
под псевдонимом ссылки
Затем объявляется и инициализируется новая переменная
В строке 18 делается попытка переназначить ссылку rSomeRef так,
но этого не происходит.
На самом же деле ссылка rSomeRef остается псевдонимом переменной intOne,
Как мы видим из результата программы после переназначения
переменная intOne стала иметь новое значение,
но ссылка rSomeRef все равно ссылается на intOne а не на ontTwo !
Назад |
Начало урока |
Вверх |
Вперед
Что такое ссылка?
Пробел перед оператором ссылки обязателен(в отличие от пробела
между оператором ссылки и именем ссылки). Таким образом
оба объявления приведенные ниже верны:
int &rSomeRef=someInt; //правильно
int & rSomeRef=someInt;//правильно
int intOne;
int &rSomeRef = intOne;
cout << "intOne: " << intOne << endl;
cout << "rSomeRef: " << rSomeRef << endl;
cout << "intOne: " << intOne << endl;
cout << "rSomeRef: " << rSomeRef << endl;
return 0;
int intOne;
инициализируемая адресом переменной intOne.
int &rSomeRef = intOne;
Ссылки, в отличие от указателя необходимо инициализировать при объявлении.
intOne = 5;
cout << "rSomeRef: " << rSomeRef << endl;
Далее ссылке присваивается значение 7.
rSomeRef = 7;
число 7 в действительности присваивается переменной intOne,
что и подтверждается выводом на экран.
cout << "intOne: " << intOne << endl;
cout << "rSomeRef: " << rSomeRef << endl;
Что происходит с самим объектом, то же происходит и со ссылкой!
Использование в ссылках оператора обращения к адресу (&)
//Listing 9.2
// Demonstrating the use of References
#include <iostream>
int &rSomeRef = intOne;
cout << "intOne: " << intOne << endl;
cout << "rSomeRef: " << rSomeRef << endl;
cout << "&rSomeRef: " << &rSomeRef << endl;
Результат:
intOne: 5
rSomeRef: 5
&intOne: 0x3500
&rSomeRef: 0x3500
Во вторых двух выводах выводятся два адреса конечно они одинаковы,
так как это объект и ссылка на него.
int intOne;
int &rSomeRef = intOne;
intOne = 5;
cout << "intOne: " << intOne << endl;
cout << "rSomeRef: " << rSomeRef << endl;
cout << "&intOne: " << &intOne << endl;
cout << "&rSomeRef: " << &rSomeRef << endl;
Обратите внимание на различие между символом & в строке 9,
который объявляет ссылку rSomeRef на значение типа int,
int &rSomeRef = intOne;
целочисленной переменной intOne и ссылки rSomeRef
cout << "&intOne: " << &intOne << endl;
cout << "&rSomeRef: " << &rSomeRef << endl;
Ссылки нельзя переназначать
Посмотрим пример:
#include <iostream>
int &rSomeRef = intOne;
cout << "intOne:\t" << intOne << endl;
cout << "rSomeRef:\t" << rSomeRef << endl;
cout << "&intOne:\t" << &intOne << endl;
cout << "&rSomeRef:\t" << &rSomeRef << endl;
18) rSomeRef = intTwo; // not what you think!
cout << "intTwo:\t" << intTwo << endl;
cout << "rSomeRef:\t" << rSomeRef << endl;
cout << "&intTwo:\t" << &intTwo << endl;
cout << "&rSomeRef:\t" << &rSomeRef << endl;
return 0;
intOne: 5
rSomeRef: 5
&intOne: 0x213e
&rSomeRef: 0x213e
intTwo: 8
rSomeRef: 8
&intTwo: 0x2130
&rSomeRef: 0x213e
int intOne;
int &rSomeRef = intOne;
intOne = 5;
cout << "intOne: " << intOne << endl;
cout << "rSomeRef: " << rSomeRef << endl;
cout << "&intOne:\t" << &intOne << endl;
cout << "&rSomeRef:\t" << &rSomeRef << endl;
int intTwo = 8;
чтобы она стала псевдонимом переменной intTwo,
18) rSomeRef = intTwo; // not what you think!
поэтому такое присвоение эквивалентно следующей операции:
intOne=intTwo;
intOne: 8 //новое значение!
intTwo: 8
rSomeRef: 8
&intOne: 0x213e
&intTwo: 0x2130
&rSomeRef: 0x213e //адрес у rSomeRef такой же как у переменной intOne !!
И не удивительно, веть это все та же переменная intOne под своим псевдонимом!
Инициализируйте ссылки при объявлении.
Не путайте оператор обращения к адресу с оператором ссылки.
Содержание