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

StackOverflow https://stackoverflow.com/questions/30998

  •  09-06-2019
  •  | 
  •  

Вопрос

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

Console::WriteLine("hello")

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

О чем static const?

Это было полезно?

Решение

но хорошо это или плохо

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

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

Другие советы

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

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

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

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

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

   private:
     static void f2 () {}
};

Как вы можете видеть, общедоступная статическая функция f1 вызывает другую статическую, но закрытую функцию f2.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top