Почему используются пространства имен? - PullRequest
2 голосов
/ 04 августа 2020

Это меня очень смущает. Все примеры кода namespaceA и namespaceB, а имена методов foo() и bar() тоже не помогают. То, как все объясняют это, создает впечатление, будто пространства имен - это c до OOP времен, когда вы не могли бы сказать «классный автомобиль дает уровень топлива», но должны были go к этому из другого подхода. Но когда я хочу перейти на уровень C ++, в чем смысл использования пространств имен? Не то, чтобы заголовки уже достаточно сбивали с толку, пространства имен не имеют для меня абсолютно никакого смысла ни в том, как они работают, ни в том, зачем их использовать.

Допустим, у меня есть проект, построенный, например, на основе Traffic. У вас были бы классы для Car s и его компонентов, Driver s и Passenger s и Road. Теперь Road имеет Car s, а каждый Car имеет Person s. Как бы это выглядело?

Были бы у вас пространства имен Road, Car, Person? Будет ли main() использовать пространство имен Road для доступа к материалам в заголовке? Будет ли пространство имен Road включать пространство имен Car, а Car включать пространство имен Person, и будет ли через это main() доступ к методам в Person? Именно так объясняют это большинство руководств, но я не вижу в этом преимущества перед простым импортом файла заголовка, разве это не будет иметь такой же эффект?

Или вы бы поместили несколько заголовков в файл одно и то же пространство имен, например namespace Traffic, со всеми этими классами? Можете ли вы вкладывать пространства имен?

Я знаю C# и никогда не знал, что у него есть пространства имен, пока я не посмотрел его только сейчас, и он никогда не нуждался, а в Java, Python и Dart они тоже никогда не подходил. Поскольку я пытаюсь научиться C ++, я сейчас как бы в затруднительном положении, задавая этот вопрос здесь. До сих пор я никогда не использовал их в C ++, но хочу выучить его как следует.

Ответы [ 4 ]

6 голосов
/ 04 августа 2020

Для небольших, автономных проектов нет особой необходимости в пространствах имен, и вы никогда не создадите пространство имен для каждого объекта или концепции в своем коде.

Более крупные проекты, использующие библиотеки, выигрывают от изоляции от имена, введенные этими библиотеками, а также некоторая внутренняя организация для облегчения чтения.

Точно так же, когда создает библиотеку, рекомендуется поместить ее содержимое в пространство имен, чтобы не чтобы вызвать головную боль и конфликты у ваших пользователей (поскольку вы не знаете, насколько велики будут их проекты и какие имена они могут захотеть использовать сами).

Используйте аналогию: если у вас есть три книги, вы не утруждаетесь их организацией в алфавитном порядке. Но когда у вас будет сотня, вы можете решить распределить их по категориям на своей книжной полке для облегчения справки и психического здоровья.

И, если вы теперь одолжите еще двадцать книг у друга, вы, вероятно, оставите их в отдельная куча, чтобы их было легче найти, когда вам нужно их вернуть.

Так что, в некоторой степени, это случай… вы будете знать, зачем вам это нужно, когда вам это нужно.

2 голосов
/ 04 августа 2020

Если я сделаю библиотеку с функцией calculateStuff() в ней, а вы также создадите библиотеку с функцией calculateStuff(), то у другого человека, который захочет использовать обе наши библиотеки одновременно, будет плохой день. Но если мы оба использовали пространства имен, проблем не возникнет, поскольку он / она сможет различать guish функции как myNamespace::calculateStuff() и yourNamespace::calculateStuff(), и нет двусмысленности.

Например: std::shared_ptr vs boost::shared_ptr. Без пространств имен вы не смогли бы использовать оба в одной программе, так как имя shared_ptr было бы неоднозначным.

1 голос
/ 04 августа 2020

Проще говоря, пространства имен позволяют использовать одни и те же имена для разных контекстов.

Допустим, вы хотите создать две функции, которые принимают одни и те же параметры и выводят текст двумя разными способами, для простоты вы Я бы хотел назвать их обе print().

Поскольку они оба принимают одни и те же параметры, здесь нет шансов на перегрузку функций, но если вы поместите каждую функцию в отдельное пространство имен, а затем вызовете print(), вы можете просто изменить то, что функция будет делать, каждый раз вызывая другое пространство имен.

1 голос
/ 04 августа 2020

«[Named] Namespaces», как, возможно, предполагает название, способ подразделить пространство идентификаторов. Помимо разрешения буквальных конфликтов («у вас более одного foo ...»), это также значительно упрощает поиск foo в большой, зрелой программе, которая вполне может состоять из сотни или даже тысячи модулей.

«Имя» переменной или подпрограммы может (?) подсказывать , что это за , но может не указывать на где это так, ни контекст (не технический термин) того, к чему это относится: «это всего лишь одно имя среди многих тысяч». Но если вы теперь сгруппируете их в разумно выбранные пространства имен, вы добавите к ним уровень полезной организации . В типичной «большой большой программе», особенно в той, которая (что тоже типично ...) «не совсем вам знакома», этот дополнительный уровень хлебных крошек является большим бонусом.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...