Пространства имён и организация кода
Не давайте именам сталкиваться по мере роста программ
audio::play и video::play.
- объяснить проблему конфликта имён и почему компоновщик не может молча выбрать победителя,
- определить пространство имён и обращаться к его членам через оператор разрешения области видимости
::, - осознанно выбирать между квалифицированным именем, using-объявлением и using-директивой,
- использовать вложенные пространства имён, псевдонимы и безымянные пространства,
- раскладывать многофайловую программу так, чтобы заголовки объявляли, а исходные файлы определяли, не нарушая правило одного определения.
1. Проблема конфликта имён
Каждая объявленная функция, класс и глобальная переменная вводит имя в некоторую область видимости. В крошечной программе это безобидно. Но реальные проекты связывают ваш код с сторонними библиотеками, и имена не обязаны быть уникальными. Допустим, сетевая библиотека и библиотека баз данных обе предоставляют свободную функцию с именем connect:
// net.h
int connect(); // open a network socket
// db.h
int connect(); // open a database session
// main.cpp
#include "net.h"
#include "db.h"
int main() {
return connect(); // ERROR: which connect() is this?
}
Компилятор видит два объявления connect с одинаковой сигнатурой. Он не может знать, что вы имели в виду, а если бы обе функции были определены, компоновщик сообщил бы о дублировании символа. Это конфликт имён. Переименовать чужие библиотечные функции получается не всегда, поэтому C++ даёт инструмент для устранения неоднозначности: поместить каждый набор имён в собственное пространство имён.