Пространство имен C ++ и включает - PullRequest
29 голосов
/ 23 декабря 2008

Зачем нам нужно использовать пространство имен и включать директивы в программах на C ++?

Например,

#include <iostream>

using namespace std;

int main() {
 cout << "Hello world";
}

Почему недостаточно просто иметь #include или просто "использовать пространство имен std" и избавиться от другого?

(я думаю о аналогии с Java, import java.net. * Импортирует import все с java.net вам больше ничего не нужно делать.)

Ответы [ 11 ]

2 голосов
/ 24 декабря 2008

Даже Страуструп называет механизм #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 не разрешать автономные функции (область действия класса является чем-то вроде пространства имен и снижает риск загрязнения глобального пространства имен), поэтому у них есть другое решение этой проблемы. Однако все еще возможно иметь некоторую двусмысленность относительно того, какой метод вы вызываете (скажем, конфликт имен между двумя интерфейсами, которые наследует класс), и в этом случае все три языка требуют, чтобы программист четко указал, какой метод они вызывают. на самом деле ищет, обычно добавляя имя родительского класса / интерфейса.

...