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

   ⁄ 

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

  ⁄   

Допустим, вам нужно заехать к дальним родственникам в другой город, у вас есть только адрес: 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 (16 оценок, среднее: 4,88 из 5)
Загрузка...
Поделиться в:
Подписаться на обновления:

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

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