Урок №57. using-стейтменти

  Юрій  | 

  Оновл. 4 Вер 2021  | 

 289

Якщо ви часто використовуєте Стандартну бібліотеку C++, то постійне додання std:: до використовуваних об’єктів може бути набридливим, чи не так? Мова C++ надає альтернативу у вигляді using-стейтментів.

Використання “using-оголошення”

Однією з альтернатив є використання “using-оголошення“. Ось програма «Hello, world!» з “using-оголошенням” в рядку №5:

Рядок using std::cout; повідомляє компілятору, що ми будемо використовувати об’єкт cout з простору імен std. І кожен раз, коли компілятор стикатиметься з cout, він розумітиме, що це std::cout.

Звичайно, в цьому випадку ми не заощадили багато зусиль, але в програмі, де об’єкти з простору імен std використовуються сотні, якщо не тисячі разів, “using-оголошення” непогано так економлять час, зусилля та покращують читабельність коду. Також для кожного об’єкту потрібно використовувати окреме “using-оголошення” (наприклад, окреме для std::cout, окреме для std::cin і окреме для std::endl).

Хоча цей спосіб є менш привабливим, ніж використання префікса std::, він все ж є абсолютно безпечним і прийнятним.

Використання “using-директиви”

Іншою альтернативою є використання “using-директиви“. Ось програма «Hello, world!» з “using-директивою” в рядку №5:

Багато програмістів сперечаються щодо використання “using-директиви”. Оскільки з її допомогою ми підключаємо ВСІ імена з простору імен std, то ймовірність виникнення конфліктів імен значно зростає (але все ж ця ймовірність в глобальному масштабі залишається незначною). using namespace std; повідомляє компілятору, що ми хочемо використовувати все, що знаходиться в просторі імен std, тому якщо компілятор знайде ім’я, яке не зможе розпізнати, він перевірятиме його наявність в просторі імен std.

Порада: Намагайтеся уникати використання “using-директиви” (наскільки це можливо).

Приклад конфлікту з “using-директивою”

Розглянемо приклад, де використання “using-директиви” створює невизначеність:

Тут компілятор не зможе зрозуміти, чи використовувати std::cout чи функцію cout(), яку ми визначили самі. В результаті отримаємо помилку неоднозначності. Хоча це і банальний приклад, але якби ми додали префікс std:: до cout:

Чи використали би “using-оголошення” замість “using-директиви”:

Тоді наша програма була б без помилок.

Більшість програмістів уникають використання “using-директиви” саме з цієї причини. Інші вважають це прийнятним доти, доки “using-директива” використовується тільки в межах окремих функцій (що значно зменшує масштаби виникнення конфліктів імен).

Область видимості “using-оголошення” і “using-директиви”

Якщо “using-оголошення” чи “using-директива” використовуються в блоці, то вони застосовуються тільки всередині цього блоку (за звичайними правилами локальної області видимості). Це добре, оскільки зменшує масштаби виникнення конфліктів імен до окремих блоків. Однак багато початківців пишуть “using-директиву” в глобальній області видимості (поза функцією main() або взагалі поза будь-яких функцій). Цим вони витягують всі імена з простору імен std безпосередньо в глобальну область видимості, значно збільшуючи ймовірність виникнення конфліктів імен. А це вже не є добре.

Правило: Ніколи не використовуйте using-стейтменти поза тілом функцій.

Відміна/заміна using-стейтментів

Як тільки один using-стейтмент був оголошений, його неможливо скасувати або замінити іншим using-стейтментом в межах області видимості, в якій він був оголошений, наприклад:

Найкраще, що ви можете зробити — це навмисно обмежити область застосування using-стейтментів з самого початку, використовуючи правила локальної області видимості:

Звичайно, весь цей головний біль можна було б уникнути, просто використавши оператор дозволу області видимості (::).

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

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

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

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