Вот карта памяти;представление памяти в виде последовательности блоков:
address 01 02 03
+----+----+----+...
data within | 23 | 6f | 4a |
+----+----+----+...
Теперь предположим, что мы создаем символ:
char c = 'z'; // 'z' is 7a in hex
Далее предположим, что c
хранится по адресу 01
, поэтому нашпамять выглядит так:
address 01 02 03
+----+----+----+...
data within | 7a | 6f | 4a |
+----+----+----+...
Теперь давайте создадим указатель:
char* p = &c; // point at c
p
может храниться по адресу 02
:
address 01 02 03
+----+----+----+...
data within | 7a | 01 | 4a |
+----+----+----+...
Здесь указатель p
находится по адресу 02
, а указывает по адресу 01
.В этом смысл p = &c;
.Когда мы разыменовываем указатель p
(по адресу 02
), мы смотрим на то, что в адресе, указанном p
.То есть p
указывает на адрес 01
, поэтому разыменование p
означает поиск внутри адреса 01
.
Наконец, давайте создадим ссылку:
char& r = c;
Здесьрасположение памяти не меняется.То есть память не используется для хранения r
.r
является своего рода псевдонимом для c
, поэтому, когда мы ссылаемся на r
, мы практически ссылаемся на c
.r
и c
концептуально едины.Изменение r
означает изменение c
, а изменение c
означает изменение r
.
При создании ссылки вы должны инициализироваться, и после инициализации вы не сможете повторно инициализировать ее с другой целью.То есть над ссылкой r
означает и навсегда будет означать c
.
Также связаны const ссылки .Это то же самое, что и ссылка, за исключением того, что они неизменны:
const char& r = c;
r = 'y'; // error; you may not change c through r
c = 'y' // ok. and now r == 'y' as well
Мы используем ссылки const, когда мы заинтересованы в чтении данных, но не одобряем их изменение.Используя константную ссылку, компилятор не будет копировать данные, поэтому это дает нам идеальную производительность, но также запрещает нам изменять данные для корректности.
В некотором смысле вы можете сказать, что ссылки являются компиляцией-time функция, тогда как указатели являются функцией времени выполнения.Таким образом, ссылки быстрее и дешевле, чем указатели, но имеют определенные ограничения и последствия.Как и другие альтернативы времени компиляции и времени исполнения, мы иногда выбираем одно из другого для повышения производительности, иногда для статического анализа, а иногда для гибкости.