Пространства имён в C++: избегайте конфликтов имен
Представьте ситуацию: в одном классе два человека с именем Зара. Чтобы их различать, нужна дополнительная информация — район проживания, имя матери или отца и т.д.
То же может произойти в C++ приложениях. Например, вы пишете код с функцией xyz(), а подключаемая библиотека тоже имеет функцию xyz(). Компилятор не знает, какую версию вы имеете в виду.
Пространство имён (namespace) создано для преодоления этой трудности и служит дополнительной информацией для различения похожих функций, классов, переменных с одинаковыми именами в разных библиотеках. Используя пространство имён, можно определить контекст, в котором определены имена. По сути, пространство имён задаёт область видимости.
Определение пространства имён
Определение начинается с ключевого слова namespace, за которым следует имя пространства:
namespace имя_пространства {
// объявления кода
}
Для вызова версии функции или переменной с пространством имён, нужно добавить префикс :: с именем пространства:
имя::код; // код — переменная или функция
Пример области видимости сущностей (переменных и функций) в пространстве имён:
Live Demo#include <iostream>
using namespace std;
// первое пространство имён
namespace first_space {
void func() {
cout << "Inside first_space" << endl;
}
}
// второе пространство имён
namespace second_space {
void func() {
cout << "Inside second_space" << endl;
}
}
int main() {
// Вызов функции из первого пространства
first_space::func();
// Вызов функции из второго пространства
second_space::func();
return 0;
}
Результат:
Inside first_space Inside second_space
Директива using
Можно избежать префикса пространства имён с помощью директивы using namespace. Она сообщает компилятору, что последующий код использует имена из указанного пространства. Пространство имён становится подразумеваемым для следующего кода:
Live Demo#include <iostream>
using namespace std;
namespace first_space {
void func() { cout << "Inside first_space" << endl; }
}
namespace second_space {
void func() { cout << "Inside second_space" << endl; }
}
using namespace first_space;
int main() {
// Вызов функции из первого пространства
func();
return 0;
}
Результат:
Inside first_space
Директива using также может ссылаться на конкретный элемент пространства имён. Если из std нужен только cout, можно написать:
using std::cout;
Последующий код может обращаться к cout без префикса, но другие элементы std всё ещё нужно указывать явно:
#include <iostream>
using std::cout;
int main() {
cout << "std::endl is used with std!" << std::endl;
return 0;
}
Результат:
std::endl is used with std!
Имена, введённые директивой using, подчиняются обычным правилам области видимости. Имя видно от точки директивы using до конца области, где она найдена. Сущности с тем же именем во внешней области скрываются.
Разрозненные пространства имён
Пространство имён может быть определено в нескольких частях, поэтому оно состоит из суммы своих отдельно определённых частей. Отдельные части могут быть разнесены по нескольким файлам.
Если одна часть пространства имён требует имени, определённого в другом файле, это имя всё равно должно быть объявлено. Написание следующего определения либо создаёт новое пространство имён, либо добавляет новые элементы к существующему:
namespace имя_пространства {
// объявления кода
}
Вложенные пространства имён
Пространства имён могут быть вложенными — одно пространство внутри другого:
namespace имя_пространства1 {
// объявления
namespace имя_пространства2 {
// объявления
}
}
Доступ к членам вложенного пространства через операторы разрешения:
// для доступа к членам имя_пространства2 using namespace имя_пространства1::имя_пространства2; // для доступа к членам имя_пространства1 using namespace имя_пространства1;
Если используется имя_пространства1, элементы имя_пространства2 становятся доступными в области видимости:
#include <iostream>
using namespace std;
namespace first_space {
void func() { cout << "Inside first_space" << endl; }
namespace second_space {
void func() { cout << "Inside second_space" << endl; }
}
}
using namespace first_space::second_space;
int main() {
func(); // вызывает функцию из second_space
return 0;
}
Результат:
Inside second_space
Язык C
- Освоение операторов C++: полное руководство с практическими примерами
- Комментарии в C++: лучшие практики для читаемого и поддерживаемого кода
- Шаблоны классов в C++: практическое руководство
- Язык программирования C++: обзор и ключевые особенности
- Константы и литералы в C++: типы, синтаксис и лучшие практики
- Полное руководство по операторам C++: типы, использование и лучшие практики
- Работа с числовыми типами в C++: практическое руководство
- Ссылки в C++: ключевые концепции и отличия от указателей
- Пространства имён в C++: избегайте конфликтов имен
- Шаблоны в C++: руководство по обобщённому программированию