Пространства имен

Пространства имен предназначены для предотвращения конфликтов идентификаторов внутри программы. Например, в вашей программе объявлена функция с названием sum(). В один прекрасный момент вам понадобились возможности библиотеки стороннего разработчика, а в этой библиотеке также объявлена функция с названием sum(). При подключении библиотеки произойдет конфликт имен. Чем меньше идентификаторов в глобальной области видимости, тем меньше конфликтов будет в программе.

Подобные конфликты возникали и при использовании стандартной библиотеки. Поэтому идентификаторы стандартной библиотеки C++ размещаются в пространстве имен std. Чтобы получить доступ к этим идентификаторам необходимо указать название пространства имен перед идентификатором. Между названием пространства имен и идентификатором указывается оператор ::. Пример:

std::cout << "Текст, выводимый в окно консоли";

Следует учитывать, что заголовочные файлы из стандартной библиотеки, имеющие расширение h, по-прежнему помещают все идентификаторы в глобальное пространство имен.

Для объявления пространства имен предназначено ключевое слово namespace. Формат объявления пространства имен:

namespace <Название пространства имен> {
   // Объявления идентификаторов
}

Обратите внимание на то, что пространство имен должно быть объявлено в глобальной области видимости. Пример объявления пространства имен NS и переменной x внутри:

namespace NS {
   int x = 10;
}

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

std::cout << NS::x << std::endl;

Допускается объявление одного пространства имен несколько раз, а также вложение одного пространства имен в другое. Пример:

namespace NS {
   namespace NS2 {
      int y = 30;
   }
}

Если необходимо получить доступ к идентификаторам, объявленным во вложенном пространстве имен, то перед названием идентификатора перечисляются названия нескольких пространств имен:

std::cout << NS::NS2::y << std::endl;

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

std::cout << ::z << std::endl;

С помощью ключевого слова using можно импортировать все или только определенные идентификаторы из пространства имен в глобальную или локальную область видимости. Импорт всех идентификаторов выглядит так:

using namespace <Название пространства имен>;

При импорте отдельных идентификаторов используется следующий формат:

using <Название пространства имен>::<Идентификатор>;

Пример использования пространств имен приведен в листинге 3.6.

Листинг 3.6. Пространства имен

#include <iostream>

namespace NS {
   int x = 10;
   void print() {
      /*  Перед x указывать название пространства имен
       *  не нужно, так как x находится в той же
       *  области видимости
       */
      std::cout << x << std::endl;
   }
}
namespace NS { // Пространство объявлено дважды
   int y = 20;
   // Вложенное пространство имен
   namespace NS2 {
      int z = 30;
   }
}

int main() {
   std::cout << NS::x << std::endl; // 10
   NS::print(); // 10
   // Доступ к идентификаторам вложенного пространства имен
   std::cout << NS::NS2::z << std::endl; // 30
   // Импорт только идентификатора y
   using NS::y;
   std::cout << y << std::endl; // 20
   // Импорт всех идентификаторов
   using namespace NS;
   std::cout << x << std::endl; // 10
   print(); // 10
   return 0;
}

В небольших программах можно импортировать все идентификаторы из пространства имен std в глобальное пространство имен (листинг 3.7). Для этого используется следующая инструкция:

using namespace std;

Теперь перед объектом cout и константой endl название пространства имен std указывать не нужно:

cout << "Текст, выводимый в окно консоли" << endl;

Хотя это очень удобно, следует избегать импортирования всех идентификаторов в глобальное пространство имен, так как возможен конфликт имен. Вместо этого способа лучше импортировать определенные идентификаторы. Например, импортировать только идентификаторы cout и endl можно так:

using std::cout;
using std::endl;

Если необходимо импортировать все идентификаторы, то следует ограничить область видимости. Например, указать инструкцию using внутри функции. В этом случае область видимости ограничена рамками функции и в глобальное пространство имен идентификаторы не попадут.

Листинг 3.7. Импорт идентификаторов из std в глобальное пространство имен

#include <iostream>
#include <clocale>

using namespace std;

int main() {
   setlocale(LC_ALL, "Russian_Russia.1251");
   cout << "Текст, выводимый в окно консоли" << endl;
   return 0;
}

В языке C++ существуют также неименованные пространства имен. Идентификаторы, объявленные в таком пространстве имен, видны только в пределах файла. Формат объявления неименованного пространства имен:

namespace {
   // Объявления идентификаторов
}

Обращение к идентификаторам неименованного пространства имен осуществляется так же как к глобальным идентификаторам. Пример использования неименованного пространства имен приведен в листинге 3.8.

Листинг 3.8. Неименованные пространства имен

#include <iostream>

// Неименованное пространство имен
// Область видимости ограничена файлом
namespace {
   int x = 10;
}

int main() {
   std::cout << x << std::endl; // 10
   return 0;
}

Учебник C++ (MinGW-W64)
Учебник C++ (MinGW-W64) в формате PDF

Помощь сайту

ЮMoney (Yandex-деньги): 410011140483022

ПАО Сбербанк:
Счет: 40817810855006152256
Реквизиты банка:
Наименование: СЕВЕРО-ЗАПАДНЫЙ БАНК ПАО СБЕРБАНК
Корреспондентский счет: 30101810500000000653
БИК: 044030653
КПП: 784243001
ОКПО: 09171401
ОКОНХ: 96130
Скриншот реквизитов