Использует слишком много статического плохого или хорошего?

Мне нравится использовать статические функции в С++ как способ их категоризации, например, С#.

Console::WriteLine("hello")

Это хорошо или плохо? Если функции используются часто, я думаю, это не имеет значения, но если они не оказывают давления на память?

Как насчет static const?

Ответ 1

но хорошо или плохо.

Первое прилагательное, которое приходит на ум, "ненужно". У С++ есть свободные функции и пространства имен, так зачем вам ставить их в классе?

Использование статических методов в неинтуитивных классах в С# и Java является обходным путем, поскольку эти языки не имеют свободных функций (то есть функций, которые находятся непосредственно в пространстве имен, а не как часть класса). У С++ нет этого недостатка. Просто используйте пространство имен.

Ответ 2

Я использую статические функции. Они просто имеют смысл, особенно когда они организованы в модули (static class в С#).

Однако, в тот момент, когда эти функции нуждаются в каких-то внешних (non compile-time const) данных, тогда эта функция должна быть сделана методом экземпляра и инкапсулирована вместе с ее данными в класс.

В двух словах: статические функции в порядке, статические данные плохие.

Ответ 3

Те, кто говорит, что статические функции могут быть заменены пространствами имен неправильными, вот простой пример:

class X
{
   public:
   static void f1 ()
   {
      ...
      f2 ();
   }

   private:
     static void f2 () {}
};

Как вы можете видеть, public static function f1 вызывает другую статическую, но частную функцию f2.

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

Многие используют шаблон "singleton", просто потому, что это обычная практика, но во многих случаях вам нужен класс с несколькими статическими методами и только один статический член данных. В этом случае нет необходимости в синглете вообще. Также вызов метода instance() происходит медленнее, чем просто доступ к статическим функциям/членам напрямую.

Ответ 4

Используйте пространства имен для создания набора функций:

namespace Console {
    void WriteLine(...) // ...
}

Что касается памяти, функции используют ту же сумму вне функции, что и статическая функция-член или в пространстве имен. То есть: никакой другой памяти, кроме самого кода.

Ответ 5

Согласитесь с Фрэнком здесь, нет проблем со статическими (глобальными) функциями (конечно, если они организованы). Проблемы только начинают ползти, когда люди думают: "О, я просто сделаю область на этом бите данных немного шире". Скользкий склон:)

Сделать это действительно в перспективе.. Функциональное программирование;)

Ответ 6

Одна из причин, почему статические данные плохи, заключается в том, что С++ не дает никаких гарантий относительно порядка инициализации статических объектов в разных единицах перевода. На практике это может вызвать проблемы, когда один объект зависит от другого в другой единицы перевода. Скотт Майерс обсуждает это в статье 26 своей книги "Более эффективный С++".

Ответ 7

Я стараюсь создавать классы, которые состоят из статических функций, но некоторые говорят, что "правильный путь" для этого обычно используется вместо пространств имен. (Я разработал свои привычки, прежде чем С++ имел пространства имен.)

Кстати, если у вас есть класс, состоящий только из статических данных и функций, вы должны объявить конструктор частным, поэтому никто не пытается его создать. (Это одна из причин, почему некоторые утверждают, что используют пространства имен, а не классы.)

Ответ 8

Проблема со статическими функциями заключается в том, что они могут привести к созданию структуры, которая разрушает инкапсуляцию. Например, если вы обнаружили что-то вроде:

public class TotalManager
{
    public double getTotal(Hamburger burger)
    {
        return burger.getPrice() + burget.getTax();
    }
}

... тогда вам может потребоваться переосмыслить ваш дизайн. Статические функции часто требуют использования сеттеров и геттеров, которые загромождают API класса и усложняют работу в целом. В моем примере было бы лучше удалить гамбургеры и просто переместить класс getTotal() в сам Гамбург.

Ответ 9

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

Для глобальных данных мне нравится использовать шаблон singleton, поскольку он помогает с проблемой неизвестного порядка инициализации статических объектов. Другими словами, если вы используете объект как одноэлементный, он гарантированно будет инициализирован при его использовании.

Также убедитесь, что ваши статические функции не имеют состояния, поэтому они безопасны в потоке.

Ответ 10

Обычно я использую только статику в сочетании с системой друзей.

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

Это, конечно, увеличивает количество функций, которыми обладает интерфейс класса. Чтобы избавиться от этого, я объявляю класс-помощник в исходном файле .cpp-классов (и, таким образом, невидимый для внешнего мира), сделайте его другом исходного класса, а затем переместите старые вспомогательные функции в статический (встроенный) элемент функции вспомогательного класса, передавая старый класс за ссылкой в ​​дополнение к старым параметрам.

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