Урок №54. Стейтменты using

  Юрий  | 

    | 

  Обновл. 18 Апр 2019  | 

 6998

 ǀ   3 

Если вы часто используете стандартную библиотеку 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» (насколько это возможно).

Пример конфликта c «директивой 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 (93 оценок, среднее: 4,89 из 5)
Загрузка...

Комментариев: 3

  1. Аватар Константин:

    Артем, поддерживаю — дело говоришь!

  2. Аватар Артем:

    Не понимаю, почему такой большой проблемой является использование using. Программисты должны знать, по идее, с какими словами будут возникать ошибки (мне, например, и в голову не придет назвать функцию или переменную cout или cin + когда мы пишем исходный код, если вдруг кому и придет идея назвать переменную cout, то программа покажет, что такое слово есть в библиотеке std). Только даун, уж извините, ошибется в таком моменте. При этом использование using экономит много времени. Не нужно постоянно прописывать имя библиотеки и ::

    1. Аватар Александр:

      Я искренне за Вас рад, если Вы помните ВСЕ имена из std…

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

      в примерах речь об пространстве std, но на практике может идти речь о подключении пространств имен других программистов… Вы и эти все имена запоминать планируете? Или будете вводить различные правила по использованию различных пространств имен?

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

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