Пространство имен позволяет сгруппировать функционал в отдельные контейнеры. Пространство имен представляет блок кода, который содержит набор компонентов (функций, классов и т.д.) и имеет некоторое имя, которое прикрепляется к каждому компоненту из этого пространства имен. Полное имя каждого компонента — это имя пространства имен, за которым следует оператор :: (оператор области видимости или scope operator) и имя компонента. Примером может служить оператор cout
, который предназначен для вывода строки на консоль и который определен в пространстве имен std. Соответственно чтобы обратиться к этому оператору, применяется выражение std::cout
.
Глобальное пространство имен
Если пространство имен не указано, то по умолчанию применяется глобальное пространство имен. применяется по умолчанию, если пространство имен не было определено. Все имена в глобальном пространстве имен такие же, как вы их объявляете, без прикрепления имени пространства имен. Например:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
#include <iostream> void print(const std::string&); const std::string message{"hello"}; int main() { print(message); } void print(const std::string& text) { std::cout << text << std::endl; } |
Здесь определены функции print и main и константа message и не используется никакого пространства имен. Поэтому фактически функции print и main и константа message определены в глобальном пространстве имен. В принципе для обращения к ним также можно использовать оператор ::, только без названия пространства имен, хотя это и избыточно:
1 2 3 4 |
int main() { ::print(::message); } |
Стоит отметить, что функция main
должна быть определена в глобальном пространстве имен.
Теперь рассмотрим, как определять и использовать свои пространства имен.
Определение пространства имен
Для определения пространства имен применяется ключевое слово namespace, за которым идет название имени пространства имен:
1 2 3 4 |
namespace имя_пространства_имен { // код пространства имен } |
После имени пространства имен идет блок кода, в который собственно помещаются компоненты пространства имен — функции, классы и т.д.
Например, определим пространство имен, которое назовем hello:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
#include <iostream> namespace hello { const std::string message{"hello work"}; void print(const std::string& text) { std::cout << text << std::endl; } } int main() { hello::print(hello::message); // hello work } |
Здесь в пространстве hello определена функция print и константа message. И чтобы обратиться к этим компонентам вне пространства имен hello, надо использовать его имя:
1 |
hello::print(hello::message); |
Внутри пространства имен к его компонентам можно обращаться без имени пространства имен:
1 2 3 4 5 6 7 8 9 10 11 12 |
namespace hello { const std::string message{"hello work"}; void print(const std::string& text) { std::cout << text << std::endl; } void print_default() { std::cout << message << std::endl; } } |
Вложенные пространства имен
Одно пространство имен может содержать другие пространства
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
#include <iostream> namespace console { namespace messages { const std::string hello{"hello"}; const std::string welcome{"Welcome"}; const std::string goodbye{"Good bye"}; } void print(const std::string& text) { std::cout << text << std::endl; } void print_default() { std::cout << messages::hello << std::endl; } } int main() { console::print(console::messages::hello); } |
Здесь в пространстве console определено вложенное пространство messages, которое содержит ряд констант. Для обращения к компонентам вложенного пространства имен также надо использовать его имя:
1 2 3 4 |
void print_default() { std::cout << messages::hello << std::endl; } |
Вне пространства имен console для обращения к подобным констанстам надо указывать всю цепь пространств имен:
1 2 3 4 5 |
int main() { console::print(console::messages::hello); // console { messages { hello}} } |
Директива using
Директива using позволяет ссылаться на любой компонент пространства имен без использования его имени:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
#include <iostream> namespace console { const std::string message{"hello"}; void print(const std::string& text) { std::cout << text << std::endl; } } using namespace console; // подключаем все компоненты // пространства console int main() { print(message); // указывать пространство имен не требуется } |
Здесь подключаем все компоненты пространства имен console в глобальное пространство имен. И после этого указывать имя этого пространства для обращения к его компонентам не требуется:
1 2 3 4 5 6 7 |
using namespace console; // подключаем все компоненты // пространства console int main() { print(message); // указывать пространство имен не требуется } |
Однако такое подключение может привести к нежелательным последствиям, если в глобальном пространстве имен определяются компоненты с теми же именами (например, переменная message). В этом случае мы можем подключить только отдельные компоненты:
Здесь подключаем только функцию print:
1 |
using console::print; |
Поэтому для обращения к ней не надо указывать имя пространства имен. А для обращения к любым другим компонентам надо.
Псевдонимы пространств
Если название пространства длинное, то для него можно определить псевдоним:
1 |
namespace псевдоним = название пространства имен; |
Например:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
#include <iostream> namespace console { namespace messages { const std::string message{"hello"}; } void print(const std::string& text) { std::cout << text << std::endl; } } namespace mes = console::messages; int main() { console::print(mes::message); // обращаемся к message // через псевдоним mes } |
В данном случае для пространства console::messages
устанавливается псевдоним mes
.