Класс VERSUS пространство имен, ИЛИ класс И пространство имен? [закрыто]

И класс и пространство имен?

Этот вопрос о шаблоне, который я вижу, я использую все больше и больше: наличие класса и пространства имен для связанных понятий. Я думаю, что это обусловлено главным образом артефактами языка C ++, но не полностью.

Я полагаю, что вопрос верхнего уровня: это хорошая идея? Иметь класс и пространство имен для связанных понятий?

Вопрос нижнего уровня:

Каков наилучший способ сделать это?

Класс вложен в пространство имен ?:

namespace Foo_Namespace {
   class Foo_Class {
       ...
   };
}

Или отдельный, одноранговый, класс и пространство имен?

class Foo_Class {
    ...
};
namespace Foo_Namespace {
   // non-class free functions, etc.
}

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

Следующее является слишком длинным, приводя к действительно уродливым именам Foo_Namespace :: Foo_Class

namespace Foo_Namespace {
   class Foo_Class {
       ...
   };
}

Не обязательно использовать какие-либо суффиксы или индикаторы в названии:

namespace Foo {
   class Foo {
       ...
   };
}

Но тогда я не уверен, когда смотрю на Foo :: bar (), является ли это свободной функциональной панелью в пространстве имен :: Foo, т.е. :: Foo :: bar (), или функцией-членом в классе Foo в пространстве имен :: Foo :: Foo :: бар ().

И такие имена, как :: Foo :: Foo :: bar, все еще не очень хорошие.

В настоящее время я делаю

Не обязательно использовать какие-либо суффиксы или индикаторы в названии:

namespace Foo_ns {
   class Foo {
       ...
   };
}

главным образом потому, что я обычно сначала создаю класс, а потом понимаю, что пространство имен было бы неплохо.

Интересно, следует ли мне восстановить соглашение об именах, которое я не использовал годами: _c для класса, _ns для пространств имен:

namespace Foo_ns {
   class Foo_c {
       ...
   };
}

Подробности:

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

Самая практическая причина, по которой я знаю использование пространства имен в дополнение к классу, заключается в том, что вам разрешено делать предварительные объявления свободных функций в пространстве имен, но вам не разрешено делать предварительные объявления некоторых методов класса. То есть с классом вы должны объявить все это или ничего. Принимая во внимание, что со свободными функциями в целом и свободными функциями в пространствах имен в частности, вы можете объявить это по частям. Части могут быть объявлены в разных заголовочных файлах. Вместо #inclusive массивной библиотеки только для заголовков для массивного класса, вы можете использовать предварительные объявления только для одной или двух функций. И т.п.

(См., Например,http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml#Forward_Declarations, хотя Google net опровергает предварительные декларации, а не включает заголовок.)

Другая причина состоит в том, что пространство имен позволяет самому классу оставаться маленьким.

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

Я предпочитаю иметь класс, вложенный в пространство имен Foo_ns / Foo_ns :: Foo_c, а не иметь их в качестве пиров Foo_ns / Foo_c, потому что часто классу нужны вспомогательные классы, например Foo_ns / Foo_ns :: Foo_c / Foo_ns :: Foo_Helper_c. Если класс и пространство имен являются одноранговыми, кажется странным иметь Foo_ns / Foo_c, но Foo_ns :: Foo_Helper_c.

Мне нравятся пространства имен, потому что я согласен с Андреем Александрешиу:http://laser.inf.ethz.ch/2012/slides/Alexandrescu/1-C++%20course%20parts%201%20and%202.pdf

 Class methods vs. free functions

 • Conventional wisdom: methods are cool, free functions are so 1960s
 • Yet:
   ◦ Free functions improve encapsulation over methods
   ◦ Free functions may be more general
   ◦ Free functions decouple better
   ◦ Free functions support conversions on their left-hand argument

  Surprising fact #2

    Making a function a method should be
    your last, not first, choice

  (c) 2012– Andrei Alexandrescu. 32 / 59

Лучше создавать бесплатные функции, чем методы в классах.

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

Соглашение об именах

Я использовал Foo_ns / Foo_ns :: Foo_c в прошлом

Я использую Foo_ns / Foo_ns :: Foo сейчас

(Кстати, я склонен использовать Class_Names_With_Underscores_and_Initial_Caps, а не CamelCase.)

Если это имеет смысл, я могу исключить суффикс _ns в пространстве имен - например, где пространство имен и класс (ы) не обязательно должны иметь одно и то же имя.

Мне не нравится делать их с одинаковыми именами. Рассмотрим конструктор для класса Foo внутри пространства имен foo:

:: Foo :: Foo :: Foo () vs :: Foo_ns :: Foo :: Foo ()

Последнее не намного лучше, но немного менее запутанно.

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

Заключение

Мой текущий BKM - Foo_ns / Foo_ns :: Foo, т.е.

namespace Foo_ns {
   class Foo { 
   ...
   };
}

Буду признателен за любые предложения, любые улучшения.

Или я просто сломлен за это?

Ответы на вопрос(3)

Ваш ответ на вопрос