




Я за использование статического функции. Они имеют смысл, особенно когда они организованы в модули (static class в C#).
Однако момент этим функциям нужны какие-то внешние (не константы времени компиляции) данные, тогда эту функцию следует сделать методом экземпляра и инкапсулировать вместе с данными в класс.
В двух словах: статические функции в порядке, статические данные - плохо.
Согласитесь с Фрэнком, здесь нет проблем со статическими (глобальными) функциями (конечно, при условии, что они организованы). Проблемы начинают закрадываться, когда люди думают: «О, я просто сделаю область видимости этого бита данных чуть шире ».. Скользкая трасса :)
Чтобы представить это действительно в перспективе .. Функциональное программирование;)
Одна конкретная причина, по которой статические данные плохи, заключается в том, что C++ не дает никаких гарантий относительно порядка инициализации статических объектов в разных единицах перевода. На практике это может вызвать проблемы, когда один объект зависит от другого в другой единице перевода. Скотт Мейерс обсуждает это в пункте 26 своей книги «Более эффективный C++».
Я стараюсь создавать классы, состоящие из статических функций, но некоторые говорят, что «правильный способ» сделать это, как правило, - использовать вместо них пространства имен. (Я выработал свои привычки до того, как в C++ появились пространства имен.)
Кстати, если у вас есть класс, состоящий только из статических данных и функций, вы должны объявить конструктор закрытым, чтобы никто не пытался его создать. (Это одна из причин, по которой некоторые утверждают, что следует использовать пространства имен, а не классы.)
but is it good or bad
Первое прилагательное, которое приходит на ум, - «ненужный». В C++ есть бесплатные функции и пространства имен, так зачем вам делать их статическими функциями в классе?
Использование статических методов в неустановленных классах в C# и Java это обходной путь, потому что эти языки не имеют свободных функций (то есть функций, которые находятся непосредственно в пространстве имен, а не как часть класса). В C++ такого недостатка нет. Просто используйте пространство имен.
Я согласен. +1. «статические» методы могут иметь свое применение, но я не могу их предоставить или найти во всех сообщениях, которые еще не охвачены пространствами имен. GO NAMESPACES. :-)
Проблема со статическими функциями в том, что они могут привести к нарушению инкапсуляции. Например, если вы обнаружите, что пишете что-то вроде:
public class TotalManager
{
public double getTotal(Hamburger burger)
{
return burger.getPrice() + burget.getTax();
}
}
... тогда вам, возможно, придется переосмыслить свой дизайн. Статические функции часто требуют, чтобы вы использовали сеттеры и геттеры, которые загромождают API класса и в целом усложняют задачу. В моем примере было бы лучше удалить геттеры Hamburger и просто переместить класс getTotal () в сам Hamburger.
Используйте пространства имен для создания набора функций:
namespace Console {
void WriteLine(...) // ...
}
Что касается памяти, функции используют то же количество вне функции, как статическая функция-член или в пространстве имен. То есть: никакой другой памяти, кроме самого кода.
Для организации используйте пространства имен, как уже было сказано.
Для глобальных данных мне нравится использовать шаблон одиночка, потому что он помогает решить проблему неизвестного порядка инициализации статических объектов. Другими словами, если вы используете объект как синглтон, он гарантированно будет инициализирован при использовании.
Также убедитесь, что ваши статические функции не имеют состояния, чтобы они были потокобезопасными.
Обычно я использую статику только вместе с системой друзей.
Например, у меня есть класс, который использует множество (встроенных) внутренних вспомогательных функций для вычислений, включая операции с личными данными.
Это, конечно, увеличивает количество функций, которые имеет интерфейс класса. Чтобы избавиться от этого, я объявляю вспомогательный класс в исходном файле классов .cpp (и, следовательно, невидимый для внешнего мира), делаю его другом исходного класса, а затем перемещаю старые вспомогательные функции в статический (встроенный) член. функции вспомогательного класса, передавая старый класс по ссылке в дополнение к старым параметрам.
Это делает интерфейс тонким и не требует большого списка бесплатных функций для друзей. Встраивание тоже хорошо работает, поэтому я не совсем против статики. (Я избегаю этого, насколько могу, но, используя это, мне нравится это делать.)
Те, кто говорит, что статические функции могут быть заменены пространствами имен, ошибаются, вот простой пример:
class X
{
public:
static void f1 ()
{
...
f2 ();
}
private:
static void f2 () {}
};
Как видите, общедоступная статическая функция f1 вызывает другую статическую, но частную функцию f2.
Это не просто набор функций, а интеллектуальная коллекция со своими собственными инкапсулированными методами. Пространства имен не дадут нам эту функциональность.
Многие люди используют шаблон «singleton» просто потому, что это обычная практика, но во многих случаях вам нужен класс с несколькими статическими методами и только одним статическим членом данных. В этом случае синглтон вообще не нужен. Также вызов метода instance() происходит медленнее, чем прямой доступ к статическим функциям / членам.
Вы не можете просто использовать пространства имен?