Даже Страуструп называет механизм #include
несколько хакерским. Однако это значительно упрощает раздельную компиляцию (отправляйте скомпилированные библиотеки и заголовки вместо всего исходного кода).
Вопрос действительно заключается в том, «почему C ++ - после того, как у него уже был механизм #include
- добавил пространства имен?»
Лучший пример, который я знаю о том, почему #include
недостаточно, исходит от Sun. Очевидно, у разработчиков Sun были некоторые проблемы с одним из их продуктов, потому что они написали функцию mktemp()
, у которой была та же сигнатура, что и у функции mktemp()
, которая была включена из файла, который сам был включен через заголовок проекта. хотел.
Конечно, эти две функции были несовместимы, и одна не могла использоваться вместо другой. С другой стороны, компилятор и компоновщик не осознавали этого при сборке двоичного файла, и иногда mktemp()
вызывал бы одну функцию, а иногда вызывал другую, в зависимости от порядка компиляции или компоновки различных файлов.
Проблема связана с тем фактом, что C ++ изначально был совместим с C и, по сути, поддерживал его. C и C имеет только глобальное пространство имен. C ++ решил эту проблему - в коде, который не совместим с C - через пространства имен.
И C #, и Java (1) имеют механизм пространства имен (namespace
в C #, package
в Java), (2) обычно разрабатываются с помощью IDE, которые обрабатывают ссылки на двоичные файлы для разработчика, и (3) don не разрешать автономные функции (область действия класса является чем-то вроде пространства имен и снижает риск загрязнения глобального пространства имен), поэтому у них есть другое решение этой проблемы. Однако все еще возможно иметь некоторую двусмысленность относительно того, какой метод вы вызываете (скажем, конфликт имен между двумя интерфейсами, которые наследует класс), и в этом случае все три языка требуют, чтобы программист четко указал, какой метод они вызывают. на самом деле ищет, обычно добавляя имя родительского класса / интерфейса.