Пространства имен и их использование
Пространство имён (namespace) — в программировании именованная, либо неименованная область определения переменных, типов, констант.Пространства имён используются для включения набора данных и функций в один блок, чтобы исключить конфликты с другими наборами функций. Иначе говоря, пространства имен используются для разбиения области видимости на несколько зон.
Объявление пространства имен
Синтаксис объявления пространства имен чем-то напоминает синтаксис объявления класса.Условно — это обозначение имени для области видимости, в которую будут входить компоненты пространства:
namespace имя { перечень_данных; } |
Применение пространства имен
Два одинаковых идентификатора в одной области видимости существовать не могут.Например, в одной программе невозможно создать две функции fire() с одинаковыми прототипами, одна из которых зажигала бы факел, а другая производила стрельбу из пистолета, кроме как с помощью пространства имен.
Пространства имен позволяют разместить две функции в различных областях видимости, не создавая при этом проблем. Кроме того, можно разместить все функции, связанные с определённым направлением, в отдельном пространстве имен.Например, функция fire(), зажигающая факел, попадет в пространство имен exploration (исследование) наряду с другими функциями исследования, а функция fire(), ответственная за стрельбу из пистолета, попадёт в пространство имен combat (боевое).
Пример 1
namespace combat
{
void fire()
{
cout<<"Vistrel";
}
}
namespace exploration
{
void fire()
{
cout<<"Ogon";
}
}
Для осуществления доступа к компонентам пространства имен используется оператора разрешения области видимости.Синтаксис доступа выглядит так:
#include <iostream>
using namespace std;
namespace combat
{
void fire()
{
cout<<"Vistrel";
}
}
namespace exploration
{
void fire()
{
cout<<"Ogon";
}
}
void main()
{
combat::fire();
exploration::fire();
}
Глобальное пространство имен
Глобальное пространство имен — это название области видимости самого высокого уровня, то есть той, где существуют глобальные переменные.
Чтобы обратиться к члену глобального пространства, часто приходится пользоваться оператором разрешения области видимости (::).Это необходимо, если существуют совпадающие имена в локальном и глобальном пространствах, поскольку по умолчанию всегда выбирается переменная с наименьшей областью видимости.Синтаксис обращения к имени глобального пространства следующий:
:: глобальное_имя; |
Пример 2
Повторные объявления пространств имен
Если два пространства имен имеют одинаковые имена, второе считается логическим продолжением первого.И компилятор считает идентичными конструкции следующего вида:
namespace x
{
void func1(){}
}
namespace x
{
void func2(){}
}
и
namespace x
{
void func1(){}
void func2(){}
}
C++ помещает оба пространства в одну область видимости при компиляции программы, это означает, что в дублирующихся пространствах имен не могут существовать члены с одинаковыми именами.
Пример 3
Прямой доступ к пространствам имен
Если Вы уверены, что пространство не содержит дублирующих членов, то можете произвести слияние его с глобальным пространством имен. Благодаря этому исчезает необходимость постоянно набирать идентификатор пространства имен и оператор разрешения области видимости.
Существует два метода прямого доступа к пространству имен:
Объявление using.
Директива using.
Объявление using
Объявление using показывает, что работа, будет производиться с определенным членом области видимости более низкого уровня.В результате отпадает необходимость в явном указании области видимости.Синтаксис объявления using следующий:
using имя_пространства::член;
Пример 4
#include <iostream>
using namespace std;
namespace dragon
{
int gold=50;
}
using dragon::gold;
void main()
{
cout<<gold;
}
Директива using
Директива using показывает, что работа будет производиться со всеми членами конкретного пространства имен. Директива работает также, как и объявление, с той лишь разницей, что обеспечивает прямой доступ ко всем членам пространства. Воспользовавшись ею, вы избавляетесь от необходимости уточнять имена членов этого пространства до конца программы. Перед её применением следует убедиться, что во включаемом пространстве имен отсутствуют идентификаторы, дублирующие идентификаторы глобального пространства.Синтаксис директивы using таков:
using namespace имя_пространства;
C примером использования этой конструкции вы уже сталкивались, он присутствует во всех написанных вами программах:
using namespace std;
Создание безымянных пространств имен
Давайте теперь разберёмся, каким образом можно гарантировать корректность имени, присвоенного пространству, ведь может получиться, что неким пространствам имён были присвоены одинаковые имена. Как избежать подобного конфликта, спросите Вы?! Как это ни странно — создав пространство имен без имени!!! Это связано с тем, что если создать безымянное пространство, С++ автоматически даст ему уникальное имя, которое мы с Вами, естественно, не увидим.Однако, то что имя будет уникальным — факт неоспоримый. Синтаксис объявления безымянного пространства имен следующий:
namespace
{
члены;
}
В такой ситуации С++ позволяет обращаться к компонентам безымянного пространства через операцию:: без указания имени.Вам нет необходимости объявлять это пространство (да и возможности нет, так как имени Вы не знаете).Неявное объявление using namespace добавляется автоматически после объявления самого пространства имен.
Рассмотрим пример работы с безымянным пространством имен:
Пример 5
#include <iostream>
using namespace std;
namespace
{
void func(){cout<<"::func"<<"\n";}
}
void main()
{
::func();
}
В заключение, следует отметить, что безымянные пространства носят локальный характер и могут быть использованы только в том файле, в котором они объявлены.