Урок №92. Посилання

  Юрій  | 

  Оновл. 26 Сер 2021  | 

 310

До цього моменту ми встигли розглянути 2 основних типи змінних:

   звичайні змінні, які зберігають значення напряму;

   вказівники, які зберігають адресу іншого значення (або 0), для доступу до яких виконується операція розіменування вказівника.

Посилання — це третій базовий тип змінних в мові С++.

Посилання

Посилання — це тип змінної в мові C++, який працює як псевдонім іншого об’єкта або значення. Мова C++ підтримує 3 типи посилань:

   Посилання на неконстантні значення (зазвичай їх називають просто «посилання» або «неконстантні посилання»), про що ми поговоримо на цьому уроці.

   Посилання на константні значення (зазвичай їх називають «константні посилання»), про що ми поговоримо на наступному уроці.

   У C++11 додали посилання r-value, про які ми поговоримо трішки пізніше.

Посилання (на неконстантне значення) оголошується з використанням амперсанда (&) між типом даних і ім’ям посилання:

У цьому контексті амперсанд не означає «оператор адреси», він означає «посилання на».

Посилання в якості псевдонімів

Посилання зазвичай поводяться ідентично значенням, на які вони посилаються. У цьому сенсі посилання працює як псевдонім об’єкта, на який воно посилається, наприклад:

Результат виконання програми:

9
10

У прикладі, наведеному вище, об’єкти ref і value обробляються як одне ціле. Використання оператора адреси з посиланням призведе до повернення адреси значення, на яке посилається посилання:

Короткий огляд l-value і r-value

Раніше ми вже розглядали, що таке l-value і r-value.

   l-value — це об’єкт, який має певну адресу в пам’яті (наприклад, змінна x) і зберігається за межами одного виразу.

   r-value — це тимчасове значення без певної адреси в пам’яті і з областю видимості виразу (тобто зберігається в межах одного виразу). В якості r-values можуть бути як результати виразу (наприклад, 2 + 3), так і літерали.

Ініціалізація посилань

Посилання повинні бути ініціалізовані при створенні:

На відміну від вказівників, які можуть містити нульове значення, посилання нульовими бути не можуть.

Посилання на неконстантні значення можуть бути ініціалізовані лише неконстантними l-values. Вони не можуть бути ініціалізовані константними l-values або r-values:

Зверніть увагу, в другому випадку ви не можете ініціалізувати неконстантне посилання константним об’єктом. В іншому випадку, ви б могли змінити значення константного об’єкта через посилання, що вже порушує саме поняття «константа».

Після ініціалізації змінити об’єкт, на який вказує посилання — не можна. Розглянемо наступний фрагмент коду:

Зверніть увагу, в стейтменті ref = value2; виконується не те, що ви могли б очікувати! Замість переприсвоювання ref (посилатися на змінну value2), значення з value2 присвоюється змінній value1 (на яке і посилається ref).

Посилання в якості параметрів у функціях

Посилання найчастіше використовуються в якості параметрів у функціях. У цьому контексті посилання-параметр працює як псевдонім аргументу, а сам аргумент не копіюється при передачі в параметр. Це в свою чергу підвищує продуктивність, якщо аргумент занадто великий або витратний для копіювання.

На уроці про вказівники і масиви ми говорили, що передача аргумента-вказівника в функцію дозволяє функції при розіменуванні цього вказівника напряму змінювати значення аргументу.

Посилання працюють аналогічно. Оскільки посилання-параметр — це псевдонім аргументу, то функція, яка використовує посилання-параметр, може змінювати аргумент, переданий їй, також напряму:

Результат виконання програми:

7
8

Коли аргумент x передається в функцію, то параметр функції ref стає посиланням на аргумент x. Це дозволяє функції змінювати значення x безпосередньо через ref! Зверніть увагу, змінна x не обов’язково повинна бути посиланням.

Порада: Передавайте аргументи в функцію через неконстантні посилання-параметри, якщо вони повинні бути змінені функцією в подальшому.

Основним недоліком використання неконстантних посилань в якості параметрів у функціях є те, що аргумент повинен бути неконстантним l-value (тобто константою або літералом він бути не може). Ми поговоримо про це докладніше (і про те, як це обійти) на наступному уроці.

Посилання як найлегший спосіб доступу до даних

Друге застосування посилань полягає в більш легкому способі доступу до вкладених даних. Розглянемо наступну структуру:

Припустимо, що нам потрібно працювати з полем value1 структури Something змінної other структури Other (звучить важко, але таке також зустрічається на практиці). Зазвичай, доступ до цього поля здійснювався б через other.something.value1. А що, якщо нам потрібно неодноразово отримувати доступ до цього члену? В такому випадку код стає громіздким і хаотичним. Посилання ж надають легший спосіб доступу до даних:

Таким чином, наступні два стейтменти ідентичні:

Посилання дозволяють зробити ваш код більш чистим і зрозумілим.

Посилання vs. Вказівники

Посилання — це той же вказівник, який неявно розіменовується при доступі до значення, на яке він вказує (“під капотом” посилання реалізовані за допомогою вказівників). Таким чином, в наступному коді:

*ptr і ref обробляються однаково. Тобто це одне і те ж:

Оскільки посилання повинні бути ініціалізовані коректними об’єктами (вони не можуть бути нульовими) і не можуть бути змінені пізніше, то вони, як правило, є безпечнішими за вказівники (так як ризик розіменування нульового вказівника відпадає). Однак, вони трохи обмежені в функціональності в порівнянні з вказівниками.

Якщо поставлене завдання можна вирішити за допомогою як посилань, так і вказівників, то краще використовувати посилання. Вказівники слід використовувати тільки в тих ситуаціях, коли посилання є недостатньо ефективними (наприклад, при динамічному виділенні пам’яті).

Висновки

Посилання дозволяють визначати псевдоніми для інших об’єктів або значень. Посилання на неконстантні значення можуть бути ініціалізовані лише неконстантними l-values. Вони не можуть бути переприсвоєні після ініціалізації. Посилання найчастіше використовуються в якості параметрів у функціях, коли ми хочемо змінити значення аргументу або хочемо уникнути його витратного копіювання.

Оцінити статтю:

1 Зірка2 Зірки3 Зірки4 Зірки5 Зірок (8 оцінок, середня: 5,00 з 5)
Loading...

Залишити відповідь

Ваш E-mail не буде опублікований. Обов'язкові поля відмічені *