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

Последнее обновление: 08.03.2023

Пространство имен позволяет сгруппировать функционал в отдельные контейнеры. Пространство имен представляет блок кода, который содержит набор компонентов (функций, классов и т.д.) и имеет некоторое имя, которое прикрепляется к каждому компоненту из этого пространства имен. Полное имя каждого компонента — это имя пространства имен, за которым следует оператор :: (оператор области видимости или scope operator) и имя компонента. Примером может служить оператор cout, который предназначен для вывода строки на консоль и который определен в пространстве имен std. Соответственно чтобы обратиться к этому оператору, применяется выражение std::cout.

Глобальное пространство имен

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

#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 определены в глобальном пространстве имен. В принципе для обращения к ним также можно использовать оператор ::, только без названия пространства имен, хотя это и избыточно:

int main()
{
    ::print(::message);
}

Стоит отметить, что функция main должна быть определена в глобальном пространстве имен.

Теперь рассмотрим, как определять и использовать свои пространства имен.

Определение пространства имен

Для определения пространства имен применяется ключевое слово namespace, за которым идет название имени пространства имен:

namespace имя_пространства_имен
{
	// код пространства имен
}

После имени пространства имен идет блок кода, в который собственно помещаются компоненты пространства имен - функции, классы и т.д.

Например, определим пространство имен, которое назовем hello:

#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, надо использовать его имя:

hello::print(hello::message);

Внутри пространства имен к его компонентам можно обращаться без имени пространства имен:

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;
    }
}

Вложенные пространства имен

Одно пространство имен может содержать другие пространства:

#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, которое содержит ряд констант. Для обращения к компонентам вложенного пространства имен также надо использовать его имя:

void print_default()
{
    std::cout << messages::hello << std::endl;
}

Вне пространства имен console для обращения к подобным констанстам надо указывать всю цепь пространств имен:

int main()
{
    console::print(console::messages::hello); // console { messages { hello}}
}

Директива using

Директива using позволяет ссылаться на любой компонент пространства имен без использования его имени:

#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 в глобальное пространство имен. И после этого указывать имя этого пространства для обращения к его компонентам не требуется:

using namespace console;    // подключаем все компоненты пространства console

int main()
{
    print(message); // указывать пространство имен не требуется
}

Однако такое подключение может привести к нежелательным последствиям, если в глобальном пространстве имен определяются компоненты с теми же именами (например, переменная message). В этом случае мы можем подключить только отдельные компоненты:

#include <iostream>

namespace console
{
    const std::string message{"hello"};
    void print(const std::string& text)
    {
        std::cout << text << std::endl;
    }
}

using console::print;    // подключаем только функцию print

int main()
{
    print(console::message); // надо указывать пространство для message
}

Здесь подключаем только функцию print:

using console::print;

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

Псевдонимы пространств

Если название пространства длинное, то для него можно определить псевдоним:

namespace псевдоним = название пространства имен;

Например:

#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.

Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850