Ссылки в C++ для начинающих. Поверхностное знакомство

В программировании на С++ очень часто используются ссылки.
Самый логичный вопрос, который обязан возникнуть у начинающих:

"Что такое ссылка?"

В общем случае можно найти приблизительно следующее определение: "Ссылка — это альтернативное имя, это псевдоним объекта" и прочие определения, в которых говорится, что ссылка — это другое имя объекта.
Для создания ссылки используют знак &, применяемый к типу.

Хотя можно встретить различные варианты написания:

Во всех случаях знак амперсанда связан с типом, приписанном левее. Пробелы ни на что не влияют.
Типы, к которым привязан знак амперсанда, называют ссылочными типами:

  • Создание переменной ссылочного типа — это не создание переменной, а создание нового идентификатора под какой-то объект, чаще всего уже именованный.
Создаётся ссылка так же, как создаются самые обычные переменные, объявляется тип, обозначается, что тип ссылочный, после чего даётся имя, как будто бы сделали переменную и назвали её заданным именем.

Но в отличие от обычных переменных ссылки требуют немедленной инициализации себя объектом.

Рассмотрим листинг с полноценным созданием ссылки. Ссылка по природе своей является переиначиванием уже существующих имён переменных на свой лад. Из-за того что в обычных условиях нельзя просто взять и обозначить знаком равенства имена переменных, было решено использовать специальный тип: ссылку на тип.

Чтение справа-налево поспособствует правильному пониманию объявляемых сущностей. ptr — это указатель на int; аналогично: ref-value — это ссылка на int.
И вот этот специальный тип помогает наслаивать на уже существующее имя дополнительные названия. А чтобы можно было знать, что за имя дополняется новыми для себя названиями, в ссылку нужно немедленно записать главного виновника торжества, т. е. обозначить, к чему нужно привязать созданную ссылку.
  • Создание ссылки предполагает наличие объекта в памяти, чтобы или позаимствовать имя у такого объекта, или создать альтернативное имя неименованному объекту:


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

Тут видно, что объявляется переменная x, а после этого объявленная x присваивается в переменную, у которой слева стоит знак &.
  • Если справа от названия типа стоит знак амперсанда, то имеем дело с ссылками.
Любые имена переменных — это всего-лишь идентификаторы участков памяти. Создание ссылки — это добавление нового идентификатора на уже используемый чем-то адрес памяти.
Смотрим листинг #1. Когда была создана переменная x, программа подобрала ей некоторый участок памяти. После этого была создана ссылка a и узами брака связала свою жизнь с созданной ранее переменной x.
  • За всё время своей жизни ссылка связана только с одним объектом. Переназначить объект ссылке нельзя.
Знак амперсанда, обозначающий создание ссылки, относится к типу, указываемому для переменной. Пробелы ни на что не влияют:
  • Знак &, относящийся к типу, — это ссылка. В противном случае это или взятие адреса, или битовое "И", или что-либо ещё.
В общем, если вы видите рядом с амперсандом название типа, то, значит, сиё ссылка. Ссылку объявляют и сразу привязывают к существующему объекту.
Вот только после освоения и осознания вами приведённой мной для вас информации, в пору говорить:
  • Ссылка — это псевдоним настоящему имени объекта.

В листинге #2 показывается, почему говорят, что ссылка — это ещё одно имя названию переменной. Вот есть некоторая обязательная переменная x, на имя которой ссылается ссылка a. Меняете x, поменяется и выводимое значение ссылки, ссылающейся на имя x.
В момент объявления ссылки a переменная x уже существует в природе, и ссылка a привязывается к этому объекту: теперь независимо от выбранного имени (x или a) работа будет происходить с переменной x.
Этот эффект получается, потому что переменная-ссылка a, ссылаясь на имя переменной x, как будто бы обращается к тому значению, которое в эту x записано.
Многих начинающих волнует вопрос отличия ссылки от указателя.
  • Самое главное отличие ссылки от указательной переменной в том, что ссылка не является объектом. Для названия ссылки может не отводиться место в памяти. Для указательной переменной место в памяти выделяется всегда.
Остальные отличия касаются использования ссылок в коде.
  • Ссылка не может ссылаться на несуществующий объект, указатель может. (Можно сделать, чтобы ссылка ссылалась на несуществующий объект, но в таком случае поведение программы непредсказуемо)
  • Ссылку нельзя переназначить, а указательную переменную можно.
В необходимости одномоментной инициализации вы легко убедитесь, если оставите только голое объявление ссылочного имени:


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

Ссылка не является переменной, но для удобства читателя я буду использовать термин ссылка-переменная. В листинге #3 было изменено значение переменной, к которой ссылка привязана, и это отобразилось на результате вывода ссылки-переменной на экран.
После вывода на экран происходит вероятная попытка связать ссылку-переменную с новой переменной, попытка подменить ссылку, но вместо того, чтобы привязаться к новой переменной, ссылка-переменная записывает значение в привязанную уже однажды к себе переменную. Для незнающего человека такое поведение программы может оказаться немного неожиданным: вместо переназначения имени была произведена обычная операция присвоения.
Хотели: a = адрес "y"
Получили: x = значение "y"
В общем, смысл в том, что указателем можно тыкать в разные адреса, а ссылкой можно тыкнуть в имя, и тыкнуть только единожды (при инициализации) — в другие имена уже не ткнуть, не получится.
Подводя итоги, акцентирую внимание на самом важном:
  • Ссылка — это синоним имени переменной, т. е. другое имя для использования переменной.
  • Ссылка не является переменной. Она просто буквенное обозначение для связи с каким-то единственным объектом.
  • Ссылка обязательно или ссылается на имя уже существующего значения, или ссылается на неназванное имя (пример был приведён выше).
    • На самом деле можно сделать так, чтобы ссылка ссылалась на несуществующее значение, но присутствие такой ссылки в программе делает поведение программы непредсказуемым.
  • Ссылка обязательно должна быть инициализирована.
  • Ссылка ссылается на имя объекта, но работа с названием ссылки — это работа с объектом, привязанном к ссылке.
  • При объявлении переменных ссылка создаётся с помощью знака амперсанд, пишемого правее названия типа.
  • Нельзя поменять связь ссылки {имя ссылки — имя объекта}, которая задаётся при создании ссылки.
  • Обращение к ссылке происходит так же, как обращение к обычной переменной.
  • Всякое изменение путём использования ссылки влияет не на ссылку, а на объект, к которому однажды была привязана ссылка.
  • Тип ссылки должен совпадать с типом объекта, к которому ссылка привязывается. Есть два исключения (при полиморфизме, при неявных приведениях тип не обязан совпадать точно)
  • Изменение объекта как будто бы влияет на ссылку, это иллюзия, т. к. ссылка — это идентификатор этого самого объекта.
На один объект можно задать сколь угодно ссылок. Все они будут только-лишь псевдонимами настоящему имени объекта.

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

14 комментариев на «“Ссылки в C++ для начинающих. Поверхностное знакомство”»

  1. Gamedaw:

    А что будет есть сделать так

    Автор сайта отвечает:
    В переменную b будет присвоено значение, взятое по второму имени переменной а
    в b запишется 300

  2. Герр Маннелиг:

    Спасибо, всё очень просто и доходчиво 🙂

  3. Шван:

    Спасибо, без воды объяснили.

  4. Аноним:

    Каждый понял своё. Часто неправильно.

  5. настя:

    я нихрена не поняла словечки какие то не понятные что такое сумбур? что за переменная?

  6. настя:

    я вообще далёкая но очень хочу научиться и везде вот эти непонятные слова , хоть словарь заводи

  7. настя:

    что за память какая память где она находиться зачем ёмаё

  8. настя:

    я уже 5 раз читаю и врубиться не могу

  9. настя:

    только не думайте что я тормоз , я просто хочу знать всё очень очень подробно

  10. настя:

    что за адрес переменной «а»

  11. Евгений:

    Настя, адрес переменной «а» в оперативной памяти, вы бы для начала почитали, что такое программа и как она работает, ну и про ОЗУ тоже почитайте, а потом уже про ссылки и указатели на с/с++

  12. Дарья:

    Спасибо вам больше за то, что вы делаете и КАК объясняете. Я, в принципе, все понимаю из «классических» учебников, но как доходит дело до кода, нюансов и разложения по полочкам, то тут и всплывает типичный теоретик, не способный что-то правильно делать окромя того, что было разобрано в учебниках.

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

    Вот честно — ОЧЕНЬ круто!

  13. Spirit:

    Я одного не понял — нафиг она нужна эта ссылка, если она всего лишь дублирует имя основной переменной?

  14. Аноним:

    да. Нафиг?

Добавить комментарий

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

Поиск

 
     

Случайная книга в электронном формате

https://www.litres.ru/adam-trahtenberg/php-recepty-programmirovaniya-3-e-izdanie-9523718/?lfrom=15589587
Яндекс.Метрика