Использовать слишком много статики плохо или хорошо?
мне нравится использовать статические функции в C++ как способ их категоризации, как это делает C#.
Console::WriteLine("hello")
это хорошо или плохо? Если функции используются часто, я думаю, это не имеет значения, но если нет, они оказывают давление на память?
насчет static const
?
10 ответов
но хорошо это или плохо
первое прилагательное, которое приходит на ум, это "ненужное". C++ имеет свободные функции и пространства имен, так зачем вам нужно делать их статическими функциями в классе?
использование статических методов в деинсталлируемых классах в C# и Java решение потому что эти языки не имеют свободных функций (то есть функций, которые находятся непосредственно в пространстве имен, а не как часть класса). С++ у него нет этого недостатка. Просто используйте пространство имен.
Я все за использование static функции. Они просто имеют смысл, особенно когда организованы в модули (static class
в C#).
однако, момент этим функциям нужны какие-то внешние (не компилируемые const) данные, тогда эта функция должна быть сделана методом экземпляра и инкапсулирована вместе со своими данными в класс.
в двух словах: статические функции в порядке, статические данные плохие.
те, кто говорит, что статические функции могут быть заменены пространствами имен, ошибаются, вот простой пример:
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 класса и делают вещи более сложными в целом. В моем примере может быть лучше удалить геттеры гамбургера и просто переместить класс getTotal () в гамбургер себя.
Я склонен создавать классы, состоящие из статических функций, но некоторые говорят, что "правильный способ" сделать это-обычно использовать пространства имен. (Я развил свои привычки до того, как C++ имел пространства имен.)
кстати, если у вас есть класс, состоящий только из статических данных и функций, вы должны объявить конструктор частным, поэтому никто не пытается создать его экземпляр. (Это одна из причин, по которой некоторые утверждают, что использовать пространства имен, а не классы.)
для организации используйте пространства имен, как уже указано.
для глобальных данных мне нравится использовать синглтон pattern, потому что это помогает с проблемой неизвестного порядка инициализации статических объектов. Другими словами, если вы используете объект как синглтон, он гарантированно будет инициализирован при его использовании.
также убедитесь, что ваши статические функции не имеют состояния, чтобы они были потокобезопасны.
обычно я использую статику только в сочетании с системой friend.
например, у меня есть класс, который использует много (встроенных) внутренних вспомогательных функций для вычисления материала, включая операции с частными данными.
Это, конечно, увеличивает количество функций, которые имеет интерфейс класса. Чтобы избавиться от этого, я объявляю вспомогательный класс в исходных классах .cpp-файл (и, таким образом, невидимый для внешнего мира), сделайте его другом исходного класса, а затем переместите старые вспомогательные функции в статические (встроенные) функции-члены вспомогательного класса, передавая старый класс по ссылке в дополнение к старым параметрам.
это сохраняет интерфейс тонким и не требует большого списка бесплатных функций друга. Inlining также работает хорошо, поэтому я не полностью против статики. (Я избегаю этого, насколько могу, но, используя это, мне нравится делать.)