Когда использовать пространство имен или структуру? - PullRequest
11 голосов
/ 10 апреля 2010

Я только что прочитал немного о них из http://www.cplusplus.com/doc/tutorial/namespaces/ и кажется, что структура способна на то же самое? Или даже класс в этом отношении. Может быть, кто-то здесь может лучше определить, что такое пространство имен и чем оно отличается от структуры / класса?

Ответы [ 6 ]

18 голосов
/ 10 апреля 2010

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

Чтобы просто сгруппировать функции и объекты, используя типы классов, вам нужно сделать их статическими:

struct X {
    static void f();
};

Без static вам пришлось бы создавать экземпляры типов классов, чтобы использовать их. Здесь лучше подходит пространство имен:

namespace X {
    void f();
}

Другая важная вещь - это using декларации и директивы:

namespace X {
    void f();
    void g();
}

void h() {
    using X::f;
    f(); // f() now visible in current scope
    using namespace X;
    f(); g(); // both visible
}

С типами классов просто нет механизма, который бы позволял это.

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

7 голосов
/ 11 апреля 2010

Ну, кажется, все идут на это, поэтому я добавлю свои собственные аргументы.

Перво-наперво, namespace и struct - совершенно разные звери: у них разный синтаксис и разная семантика.

Очевидное:

  • a struct вводит тип, который можно использовать в качестве аргумента шаблонов
  • a namespace может распространяться в нескольких файлах

синтаксически:

  • оба могут быть "псевдонимами", пространство имен с namespace ns = mylong::name::space; и структура с typedef mylong::name::Space lilstruct;
  • ADL (или зависимый от аргумента поиск) предназначен для пространств имен

семантически:

  • a namespace определяет только область действия для определения символов, которая позволяет группировать объекты, которые работают вместе (классы и свободные функции), в то же время изолируя их для остального мира (конфликт имен). Как таковая, она часто представляет собой логическую единицу работы в проекте (для небольших проектов существует единое пространство имен).
  • a struct или class определяет логическую связь между данными и методами воздействия на них, что является краеугольным камнем инкапсуляции. Обычно он имеет одну четкую ответственность и несколько инвариантов.

Обратите внимание, что иногда struct или class просто используются для связывания объектов, которые работают вместе, без какой-либо логики, например struct Person { std::string name, firstName; };.

При этом: в C ++ нет смысла для struct из static методов. Это просто извращение от Java или C # и их «чистый» подход к ОО. C ++ поддерживает свободные функции, поэтому нет смысла их не использовать, тем более что это лучше для инкапсуляции (у них нет доступа к закрытым / защищенным частям, поэтому вы не можете испортить инвариант, и они не зависят от представление класса либо).

2 голосов
/ 10 апреля 2010

Если это можно сделать с помощью пространства имен, используйте пространство имен.

Структура делает гораздо больше, чем просто определяет область действия. Он определяет тип.

2 голосов
/ 10 апреля 2010

При создании собственной библиотеки обычно рекомендуется использовать пространство имен для всех экспортируемых функций и классов.

Таким образом, если кто-то включает вашу библиотеку, он не будет загрязнять свое пространство имен, и вероятность столкновения имен будет меньше.

1 голос
/ 09 февраля 2016

Если вы не хотите, чтобы люди использовали в вашем классе функцию «использования» C ++, которая может быть опасной и часто не рекомендуется в сложном коде, тогда продолжайте и используйте struct со статикой ,

Другими словами: если ваши функции должны * всегда указываться с помощью "group :: function", то вы можете добавить пользователей в список, объявив их как struct.

Кроме того, и, что важно, вы можете заранее объявить структуры в более старых версиях C ++. Вы не можете делать это с пространствами имен до C ++ 11.

Рассмотрим:

std::string out zip::pack(const std::string &in)
std::string out zip::unpack(const std::string &in)

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

Рассмотрим:

std::string out CorpDataUtils::zipPack(const std::string &in)
std::string out CorpDataUtils::zipUnpack(const std::string &in)

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

1 голос
/ 10 апреля 2010

В C ++ структура в точности совпадает с классом, за исключением того, что по умолчанию структуры являются общедоступными. Занятия частные. Поэтому, когда вы хотите сгруппировать свободные функции вместе, используйте пространство имен. Если вы хотите сгруппировать данные и функции, используйте struct / class и, возможно, пространство имен вокруг всего этого.
Обратите внимание, что если вы поместите свои функции в структуру, то вам потребуется экземпляр вашей структуры, когда вы хотите вызывать эти функции, если они не являются статическими.

...