Хорошо или хорошо использовать пространство имен как статический класс? Например:
namespace MyStaticFunctions {
void doSomething();
}
Versus:
class MyStaticFunctions {
static void doSomething();
}
Хорошо или хорошо использовать пространство имен как статический класс? Например:
namespace MyStaticFunctions {
void doSomething();
}
Versus:
class MyStaticFunctions {
static void doSomething();
}
В С++ нет такой вещи, как "статический класс", поэтому с точки зрения С++ вы не используете ее как "статический класс", вы используете ее "как пространство имен". Разумеется, практика использования пространств имен объединяла функции вместе.
Тем не менее, насколько вы хотите, чтобы группы были. Для библиотек С++ не так просто использовать единое пространство имен для всего публичного интерфейса. Это может стать неожиданностью для тех, кто привык (скажем) Java, где классы часто используются для группировки меньшего количества статических методов. Поскольку С++ был здесь первым, вы могли бы сказать, что Java использует классы как пространства имен.
Итак, в С++ вы не склонны видеть классы, похожие на java.util.Collections
или java.lang.Math
, заполненные статическими членами. Если вам нужны группы таких функций, как на С++, используйте пространства имен.
Исключение (не всегда ли существует специальный случай в С++?) - это такие типы признаков, как std::numeric_limits<T>
, где параметр шаблона делает класс тем, что пространство имен не может сделать. Вы можете определить пространство имен numeric_limits
, содержащее шаблоны функций max<T>()
, min<T>()
и т.д., Но это не так хорошо. Во-первых, он группирует вещи несколько иначе, тип T
появляется "ниже иерархии". Во-вторых, это не делает все, что делает тип признаков, потому что нет такой вещи, как "шаблон объекта", который позволит вам определить значение numeric_limits::digits<T>
.
Я не знаю, С# достаточно, чтобы прокомментировать практическое использование статических классов там, но AFAIK это просто класс, ограниченный отсутствием нестатических членов, поэтому он аналогичен тем Java-классам.
В С++ вы на самом деле поощряетесь на уровне языка использовать namespace
, а не class
, содержащий только static
методы из-за поиска Koenig (также известный как поиск аргумента).
Пример:
namespace geometry {
struct Point { int x, y; };
double distance_from_center(Point const& p) {
return sqrt(p.x * p.x + p.y + p.y);
}
} // namespace geometry
int main() {
geometry::Point const p{3, 4}; // must qualify
std::cout << distance_from_center(p) << "\n"; // not qualified
}
Если distance_from_center
записывается как метод static
в class
, тогда вам нужно явно указывать его каждый раз.
Это сложный и интересный вопрос для меня лично, поэтому решил поделиться своим скромным мнением
Учитывая разницу между "статическим" классом (только статическими членами) и пространством имен:
С точки зрения обслуживания иногда вы выбираете класс "статический" (например, singleton), но тогда требование изменилось, и вам нужно несколько экземпляров. "Статический" класс легче преобразовать, чем пространство имен.
И, наконец, чтобы ответить на ваш вопрос:
если вам не нужны специальные функции "статического" класса или пространства имен, используйте то, что вам больше нравится:)
Это зависит.
Является ли метод логически связан с классом? Если это так, сделайте его членом, иначе поместите его в пространство имен.
Функционально, они одинаковы, но есть больше кода, чем функция, не так ли? Например, рассмотрим метод, который возвращает имя класса:
struct MyClass
{
static std::string getName() { return "MyClass"; }
}
Вы могли бы поместить метод снаружи в namespace
и получить тот же результат, но он логически принадлежит классу.