Хорошо, я узнал, что такое статическая функция, но я до сих пор не понимаю, почему они более полезны, чем закрытые функции-члены. Это может быть своего рода новым вопросом здесь, но почему бы не заменить вместо этого все закрытые функции-члены статическими функциями?
static-methods
Темный тамплиер
источник
источник
static
для ограничения функций областью действия файла.private member
мы можем с уверенностью предположить, что OP спрашивает о концепции OO и не имеет ни малейшего представления о статической области видимости файла.Ответы:
Предполагая, что вы используете ООП , используйте статические функции, когда они не зависят ни от каких членов класса. Они все еще могут быть частными, но таким образом они оптимизируются, поскольку они не зависят ни от какого экземпляра связанного объекта.
Помимо вышесказанного, я считаю статические функции полезными, когда вы не хотите создавать экземпляр объекта только для выполнения одной общедоступной функции над ним. Это в основном относится к вспомогательным классам, которые содержат публичные функции для выполнения некоторой повторяющейся и общей работы, но не требуют поддержания какого-либо состояния между вызовами.
источник
Попытка более простого объяснения, чем выше (довольно хорошие).
Объект - это код + данные в обычном режиме. Статический метод используется, когда у вас есть только часть кода, с которой нужно иметь дело (данные / состояние не поддерживаются (за исключением элементов статических данных)).
источник
Потому что они не требуют экземпляра и могут быть публичными. Скажем, вам нужна функция, чтобы получить наибольший общий знаменатель (GCD; очень полезно для классов дроби; да, это всего лишь простой пример). Нет смысла создавать класс объектов, единственной целью которых является то, что у вас может быть
this
указатель, в котором вы не нуждаетесь и не используете егоgcd
. Таким образом, вы используете статический метод для него, в идеале для класса, который фактически использует GCD (например, в классе дроби).Конечно, если есть только статические методы, вы неправильно выполняете ООП и должны либо перейти к выполнению ООП, либо использовать язык, более подходящий для вашей парадигмы.
источник
stuff::Thing::Load(...)
противstuff::LoadThing()
).Я использую их как вспомогательные функции для общих задач, например:
Большинство моих файлов, которые группируют статические функции, имеют суффикс Helper, означающий, что именно это они и делают, помогают мне быстрее добраться куда-то.
источник
Что касается статического метода:
Примеры использования статических методов:
Просто используйте их там, где это уместно.
Если большая часть ваших данных находится за пределами объектов и они обрабатываются статическими методами, тогда ваш код не является объектно-ориентированным и может стать трудным в обслуживании.
источник
Статические и частные фактически являются ортогональными: метод может быть статическим или частным, или ни одного, или и тем, и другим.
Статический или нестатический (он же «методы экземпляра») указывает, работает ли метод на самом классе (статический) или на одном конкретном экземпляре (нестатический). В зависимости от языка вы можете вызывать статический метод через экземпляр, но вы никогда не сможете получить доступ к экземпляру через статический метод (что также подразумевает, что вы не можете вызывать какие-либо нестатические методы из статического метода просто потому, что у вас нет
this
объект). Используйте статические методы для реализации поведения, которое концептуально связано с классом, но не привязывается к одному конкретному экземпляру. Другой сценарий, в котором вы можете захотеть использовать статические методы, - это когда у вас есть функция, которая работает с двумя экземплярами класса, и ни один из операндов не заслуживает привилегированного статуса - например, если у вас есть классVector
и вы хотите реализовать сложение; Ваш метод сложения может быть вызван какa.Add(b)
, но,Vector.Add(a, b)
вероятно, имеет больше смысла.Приватный и публичный - о видимости метода. Доступ к закрытым методам возможен только из собственной области видимости класса, тогда как открытые методы доступны из любого места. Наиболее важным использованием для этого является инкапсуляция: делая общедоступными только те методы и свойства, которые абсолютно необходимы остальной части кода для взаимодействия с вашим классом, вы ограничиваете точки, в которых внешний код может создавать проблемы, и предотвращаете проблемы внутри. Ваш класс от кровотечения до остальной части проекта.
Итак, практическое правило:
источник
Я использую статические методы как в C ++, так и в C # для классов Utility, классов, у которых нет данных экземпляра, только один из способов связать коллекцию полезных связанных методов.
источник
Предполагая, что вы говорите о C ++ (вы не сказали), и у вас есть правильные термины (то есть, они не означают функции / методы-члены):
Даже закрытая функция-член все еще должна быть объявлена в заголовке, что означает, что она фактически становится частью API и ABI класса, даже если пользователь не может вызвать ее на самом деле. Если вы добавляете, модифицируете или удаляете закрытую функцию-член, вы принудительно перекомпилируете все зависимые классы (заголовок изменился, make не может знать лучше), а когда вы делаете это в библиотеке, вы должны учитывать совместимость приложения, используя Это.
С другой стороны, статические функции с файловой областью не получают общедоступный символ, поэтому вы можете добавлять, изменять или удалять их по своему усмотрению, и ничто, кроме одного модуля компиляции, не будет затронуто.
источник
Как правило, вам нужен статический main, чтобы действовать как точка входа для вашей программы. Это может быть отчасти важно.
источник
Статическая функция (и для этого термина есть разные значения) не требует состояния, которое сохраняется между вызовами. Если он концептуально тесно связан с тем, что делает класс, сделайте его функцией класса (как в случае с классом, а не объектом) или, если нет, сделайте его глобальной (или модульной, независимо от того) функцией. Он не принадлежит объекту, если он не нуждается в состоянии объекта.
Если вы все время передаете ему состояние, которое на самом деле не является функцией без сохранения состояния, вы просто создаете функцию с сохранением состояния с синтаксисом без сохранения состояния. В этом случае он, вероятно, принадлежит вызывающему объекту, или может быть указан рефакторинг для лучшего выравнивания состояния и поведения.
источник
"Почему бы просто не заменить все закрытые функции-члены статическими?"
... потому что закрытый член может получить доступ к данным экземпляра, в то же время позволяя ему происходить только из вызовов, выполняемых внутри других функций-членов. Статическая функция может быть закрытой, но она не сможет изменять или ссылаться на экземпляр класса, если экземпляр не передан в качестве параметра.
источник
Забавно, что пока никто не смог дать хороший ответ. Я не уверен, что это тоже. Вы, вероятно, должны принять это как намек на то, что их следует использовать как можно меньше. Они все-таки процедурные, а не ООП.
Вот еще несколько примеров:
В Obj-C, где они называются методами класса, они обычно используются в качестве оболочек выделения, когда объект помещается в пул подсчета ссылок перед его возвратом.
Другой пример из Obj-C - это регистрация нового класса в коллекции классов. Допустим, у вас есть набор классов, каждый из которых обрабатывает один тип файла. Когда вы создаете новый класс для нового типа файла, вы можете зарегистрировать его в коллекции (глобальная переменная), используя статический метод в классе, который определяет тип файла.
В C ++ я могу придумать еще одно применение - мягко отлавливать ошибки. Ваша функция конструктора не может завершиться с ошибкой, кроме как с помощью исключения. Вы можете установить переменную экземпляра ошибки, но это не всегда подходит. Вместо этого вы можете выполнять части, которые могут не работать в статической оболочке, а затем выделять и возвращать новый объект или NULL в случае ошибки.
источник
Допустим, вы хотите вычислить синус чего-то.
Без статики:
Со статическим:
Нет смысла делать
sin
нестатичные. Он не имеет состояния и просто обрабатывает ввод.Статические функции не привязаны к конкретным объектам. Это «общие» функции, которые не зависят от внутреннего состояния объекта.
источник
x.sin()
. Ваш ответ предполагает, что грех должен быть функцией «математики», тогда как он явно действует на двойник.В некотором смысле здесь, но я хотел бы попытаться создать точное определение: статические функции - это функции, которые не ссылаются или не могут ссылаться на свойства / методы экземпляра содержащего класса.
В некоторых языках, таких как C #, могут быть статические поля или свойства в статических классах, поэтому не совсем правильно говорить, что они не используются для состояния; статическая функция может использовать статическое (глобальное) состояние.
По сути, это сводится к следующему: статические функции, как и все статические, полезны, когда имеет смысл, чтобы они всегда были доступны без зависимости от нестатических экземпляров.
Вспомогательные функции, такие как математические функции, являются частым примером, но есть и другие.
Если класс, который вы создаете, требует, чтобы данные были неизменными, возможно, имеет смысл создавать статические функции, которые принимают экземпляр и передают новый экземпляр, поскольку экземпляр не может (или не должен) изменяться. Строковые классы, например, могут иметь статические функции, которые принимают строку (или 2 или более) и возвращают новую строку.
Другая причина может заключаться в том, что существует класс, который хранит глобальное состояние или данные какого-либо рода. Там могут быть статические функции, которые работают со статическими свойствами или полями в этом статическом классе.
источник
Я хотел бы указать на другое использование статического f ().
http://www.parashift.com/c++-faq/named-ctor-idiom.html
Это сводится к следующему:
static
функции позволяют создавать «именованные конструкторы», т.е. вы называете статическую функцию подходящим и самодокументируемым именем, и эта статическая функция вызывает один из конструкторов (поскольку конструкторы имеют идентичные имена, и вы можете иметь их много, становится трудно их различать).источник