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

  Юрий  | 

  Обновл. 22 Сен 2020  | 

 28327

 ǀ   8 

Если вы часто используете Стандартную библиотеку 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 (274 оценок, среднее: 4,93 из 5)
Загрузка...

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

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

    Здравствуйте. Можете подсказать список всех объектов std?
    Это было бы полезно держать "под боком" во время написания программы, да и поможет запомнить наиболее часто используемые объекты.
    Заранее спасибо.

  2. Аватар Глеб:

    Не будет-ли лучшим решением написать свою функцию <<cout>> для вывода текста на дисплей экрана?

    1. Аватар Sarad:

      И как вы себе это представляете?

  3. Аватар Артемий:

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

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

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

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

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

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

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

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

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

    2. Аватар Dmitry:

      Проблема в том, мой друг Горацио, что принимаются новые стандарты языка. Может быть на сегодняшний день ты выучил все имена из стандартной библиотеки и написал суперский код, настолько популярный, что его подрубают как библиотеку во все серверные приложения. Но вот принимается новый стандарт и в этот злосчастный std могут запихивают новое имя, которое вызывает конфликт с твоим. Угадай, к кому будут вопросы после того, как либа перестанет работать?

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

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