Урок 24. Конфликт имен и std namespace

  Юрий Ворон  | 

    | 

  Обновлено 24 Фев 2017  | 

 8721

 ǀ   6 

Допустим, вам нужно заехать к дальним родственникам в другой город, у вас есть только адрес: Front Street, 245 в Mill City. Попав в Mill City, вы достаете свою карту и выясняете, что на самом деле в этом городе есть две разные улицы в разных концах города с названием Front Street! Какая же из них нужна вам? Если нет никакой дополнительной информации (например, вы знаете, что их дом находится рядом возле какой-то пекарни) вам пришлось бы позвонить им и спросить дополнительную информацию. Дабы избежать подобной путаницы и неэффективности (особенно для почтальонов), все названия улиц (и номера домов) в городе должны быть уникальными.

Так и C++ требует, чтобы все идентификаторы (имена переменных и/или функций) были уникальными. Если два идентификатора находятся в одной и той же программе таким образом, что компилятор не может различить их, он выдаст ошибку. Эта ошибка, как правило, называется конфликтом имен (или столкновением имен).

Пример конфликта имен

a.cpp:

b.cpp:

main.cpp:

Файлы a.cpp, b.cpp и main.cpp скомпилируются, так как по отдельности они в порядке, нет никаких проблем. Однако, если a.cpp и b.cpp разместить в одном проекте – произойдет конфликт, так как функция doSomething() есть в обоих файлах. Здесь ошибку выдаст линкер.

Большинство конфликтов имен происходит в двух случаях:



два файла добавлены в один проект, которые имеют функцию (или глобальную переменную) с одинаковыми именами (ошибка линкера);

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

Как только программы становятся больше и используется больше идентификаторов, вероятность столкновения имен значительно возрастает. Хорошая новость в том, что C++ предоставляет достаточно механизмов для предотвращения подобных конфликтов (например: локальная область видимости, которая содержит переменные внутри каждой функций отдельно, или пространство имен, о котором мы сейчас расскажем).

std namespace

Когда C++ был только создан, все идентификаторы в стандартной библиотеке C++ (такие как cin или cout) можно было использовать напрямую. Тем не менее, это означало, что любой идентификатор в стандартной библиотеке потенциально мог конфликтовать с именем, которое вы выбрали для ваших собственных идентификаторов. Код, который работал, мог внезапно получить конфликт имен, когда вы #include новый файл из стандартной библиотеки. Или еще хуже, программы, которые компилировались, используя одну версию C++, могли не скомпилироваться уже с использованием другой версии C++, так как новые функциональные возможности в стандартной библиотеке могли конфликтовать. Таким образом, в C++ перенесли всю функциональность со стандартной библиотеки в специальную область, которую назвали пространством имен (namespace).

Так как город гарантирует, что все улицы в его пределах имеют уникальные названия, то и пространство имен гарантирует, что все идентификаторы – уникальны (в пределах этого namespace).

Таким образом, std::cout не является на самом деле «std::cout». Это просто «cout» и «std» (название пространства имен, в котором оно находится). Все функциональные возможности стандартной библиотеки C++ определены внутри namespace std (сокращенно от «standard»). Таким образом, мы не должны беспокоиться о конфликте наших собственных идентификаторов с идентификаторами стандартной библиотеки.

Мы поговорим больше о пространствах имен в следующих уроках, а также расскажем, как создать свой собственный namespace. На данный момент, главное, что вам нужно запомнить — это то, что всякий раз, когда вы используете идентификатор (например, std::cout), который является частью стандартной библиотеки, вы должны сообщать компилятору, что этот идентификатор находится внутри пространства имен std.

Правило: когда вы используете идентификатор с пространства имен, обязательно указывайте имя этого пространства имен.

Оператор разрешения области видимости ::

Самый простой способ сообщить компилятору, что cout находится в std namespace – использовать префикс «std::». Например:

Это самый безопасный способ использовать cout, так как как здесь уже нет никакой двусмысленности о том, где находится cout (ясно, что в пространстве имен std).

Оценить статью:

Звёзд: 1Звёзд: 2Звёзд: 3Звёзд: 4Звёзд: 5 (113 оценок, среднее: 4,92 из 5)
Загрузка...

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

  1. Михаил:

    После php изучать такие языки очень интересно, ибо не слишком похоже на то, что делаю на работе. Юзаю CLion на домашнем Linux-е, ничем не хуже Visual Studio 2017, если кто-то тоже на Linux-е, рекомендую. А Вам, Юрий, большое спасибо за труд, очень легко двигаться по Вашим урокам.

    1. Юрий Ворон Юрий Ворон:

      Да, плюсы после PHP это что-то новенькое. Для программистов обязательно если не работать, то хотя бы неплохо разбираться в ОС Linux, поэтому спасибо за совет в выборе IDE 🙂

  2. Александр:

    Я конечно понимаю что использовать std::cout безопаснее, но разве не проще использовать using namespace std;? Или в других пространствах имён есть cout или cin?

  3. Андрей:

    Доброе утро. Не понял всё-таки, как надо использовать это пространство имён, в случае с приведённым выше примером, да и вообще…

  4. илья:

    извините что вопрос не по теме. существует такая программа visual studio code вроде тоже для программирования, я её установил(ради интереса) она похожа на visual studio community 2017 ( которой пользуюсь я) но я не понял для чего же она?

    1. Юрий Юрий:

      Visual Studio Code — это кроссплатформенный редактор с подсветкой синтаксиса и отладчиком. Намного упрощенная версия полноценной IDE, которой является Visual Studio.

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

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