Класс 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 {
...
};
}
Это н't необходимо использовать любые суффиксы или показатели в названии:
namespace Foo {
class Foo {
...
};
}
Но тогда я не уверен, когда смотрю на Foo :: bar (), является ли это свободной функциональной панелью в пространстве имен :: Foo, т.е. :: Foo :: bar (), или функцией-членом в классе Foo в пространстве имен :: Foo :: Foo :: бар ().
И такие имена, как :: Foo :: Foo :: bar, все еще не очень хорошие.
В настоящее время я делаю
Это н't необходимо использовать любые суффиксы или показатели в названии:
namespace Foo_ns {
class Foo {
...
};
}
главным образом потому, что я обычно сначала создаю класс, а потом понимаю, что пространство имен было бы неплохо.
Интересно, должен ли я восстановить соглашение об именах, которого у меня нет?t используется в годах: _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 {
...
};
}
Буду признателен за любые предложения, любые улучшения.
Или я просто сломлен за это?