Wann kommen statische Funktionen zum Einsatz?

24

OK, ich habe gelernt, was eine statische Funktion ist, aber ich verstehe immer noch nicht, warum sie nützlicher sind als Funktionen für private Mitglieder. Dies könnte hier eine Art neue Frage sein, aber warum nicht einfach alle privaten Member-Funktionen durch statische Funktionen ersetzen?

Dunkler Templer
quelle
1
Sollte das nicht "alle statischen Funktionen durch private Mitgliedsfunktionen ersetzen" sein? Derzeit behaupten Sie, dass Sie den Sinn statischer Methoden nicht erkennen und fragen, warum wir nicht mehr von ihnen verwenden.
5
Was ist eine "statische Funktion"? In C ++ gibt es mindestens zwei Bedeutungen (und das letzte Mal, als ich mir C ++ 11-Entwürfe angesehen habe, hatten sie die Verfallserklärung entfernt, um staticFunktionen auf den Dateibereich zu beschränken.
David Thornley,
Meinen Sie "statische Funktion" im Sinne einer statischen freien Funktion im Dateibereich in C / C ++ oder als "statische Mitgliederfunktion / -methode"? Es ist ein großer Unterschied!
Jan Hudec
@JanHudec: Ich denke, angesichts des Vorhandenseins von können private memberwir davon ausgehen, dass das OP nach dem OO-Konzept fragt und keine Ahnung von statischen Daten im Dateibereich hat.
Matthieu M.
@MatthieuM .: Eigentlich ist die Anwesenheit von 'privatem Mitglied' genau das, was mich zu der Annahme veranlasst, dass er statische Funktionen im Sinne von C ++ meint. Da statische Funktionen mit Dateibereichen und private Member-Funktionen in C ++ sehr ähnlich verwendet werden, macht das Ersetzen eines öffentlichen statischen Members durch ein privates nicht statisches Member nur wenig Sinn. Leider scheint OP nicht zu reagieren.
Jan Hudec

Antworten:

24

Angenommen, Sie verwenden OOP , verwenden Sie statische Funktionen, wenn sie nicht von Klassenmitgliedern abhängig sind. Sie können immer noch privat sein, werden jedoch auf diese Weise optimiert, da sie nicht von einer Instanz des zugehörigen Objekts abhängen.

Abgesehen von den oben genannten finde ich statische Funktionen nützlich, wenn Sie keine Instanz eines Objekts erstellen möchten, nur um eine öffentliche Funktion darauf auszuführen. Dies ist hauptsächlich bei Hilfsklassen der Fall, die öffentliche Funktionen enthalten, um sich wiederholende und allgemeine Aufgaben zu erledigen, aber zwischen den Aufrufen keinen Status beibehalten zu müssen.

Bernard
quelle
Vielen Dank, Bernard. Übrigens, wissen Sie, was es für einen Compiler bedeutet, "eine Methode an die Klasse zu binden"?
Dark Templar
@ Dark Templar: Kann ich nicht sagen. Ist das spezifisch für eine bestimmte Sprache?
Bernard
Ich habe ein kleines Problem mit Ihrer Definition "sie hängen nicht von irgendwelchen Klassenmitgliedern ab". Statische Memberfunktionen können nicht auf statische Member zugreifen, sie können jedoch auf statische Member zugreifen. Statische Mitglieder sind Mitglieder der Klasse.
Zeitungsdruck
@newprint: Du hast recht, aber das habe ich nicht gesagt. Ich sagte, wenn sie nicht auf Klassenmitglieder angewiesen sind. Die Verwendung von statischen Elementen ist in Ordnung, wenn dies erforderlich ist. Dies ist jedoch möglicherweise nicht immer der Fall.
Bernard
8

Ich versuche eine einfachere Erklärung als die oben genannten (ziemlich gute).

Ein Objekt ist normalerweise Code + Daten. Eine statische Methode wird verwendet, wenn Sie nur den "Code" -Teil bearbeiten müssen (es werden keine Daten / Zustände verwaltet (außer statische Datenelemente)).

Brian Knoblauch
quelle
5

Weil sie keine Instanz benötigen und öffentlich sein können. Angenommen, Sie benötigen eine Funktion, um den größten gemeinsamen Nenner zu erhalten (GCD; sehr nützlich für Bruchklassen; und ja, dies ist nur ein einfaches Beispiel). Es hat keinen Sinn, eine Klasse von Objekten zu erstellen, deren einziger Zweck darin besteht, dass Sie einen thisZeiger haben können, den Sie weder benötigen noch in dem Sie ihn verwenden gcd. Sie verwenden dafür also eine statische Methode, idealerweise für die Klasse, die die GCD tatsächlich verwendet (z. B. in der Bruchklasse).

Natürlich, wenn es nur statische Methoden gibt, machen Sie OOP falsch und sollten entweder zu OOP wechseln oder eine Sprache verwenden, die besser zu Ihrem Paradigma passt.

user7043
quelle
Wäre es in Ihrem Beispiel nicht besser, eine freie Funktion zu verwenden?
Ela782
2
@ Ela782 Wenn die Sprache freie Funktionen hat, ja.
Okay, danke für die Bestätigung. Ich habe diese bewährte Methode erst kürzlich gelernt. Allerdings habe ich im Moment Probleme zu erkennen, wann eine öffentliche statische Member-Funktion tatsächlich nützlich sein könnte, sagen wir in einer Sprache wie C ++. Der Anwendungsfall für beide ist, wenn die Funktion nicht von der Klasse abhängt oder eine Instanz der Klasse benötigt und dann freie Funktionen die Empfehlung sind. Vielleicht sollte dies eine neue Frage sein.
Ela782
1
@ Ela782 Ja, es könnte eine gute Frage sein. Zwei wichtige Punkte: Insbesondere in C ++ sind statische Member für die Metaprogrammierung von Vorlagen nützlich, da Sie einen Typ als Vorlagenparameter, jedoch keinen Namespace übergeben können. Im Allgemeinen können statische Funktionen verwendet werden, um anzuzeigen, dass die Funktion zu einer bestimmten Klasse gehört, anstatt nur in einen Namespace zu gehören (think stuff::Thing::Load(...)vs stuff::LoadThing()).
2

Ich benutze sie als Hilfsfunktionen für allgemeine Aufgaben, zum Beispiel:

  • Grad in Bogenmaß umrechnen (und umgekehrt);
  • Hashing einer Zeichenfolge;
  • Umwandlung von einer Aufzählung in etwas anderes (in diesem Projekt, an dem ich arbeite, fungieren sie als Hash-Tabelle);

Die meisten meiner Dateien, die statische Funktionen gruppieren, haben das Suffix Helper, was bedeutet, dass sie das tun, was mir hilft, schneller irgendwohin zu gelangen.

George Silva
quelle
2

Was eine statische Methode ist:

Statische Methoden erfordern weder eine Instanz der Klasse, noch können sie implizit auf die Daten (oder dies, Selbst, Ich usw.) einer solchen Instanz zugreifen. [ 1 ]

Beispiele, wann statische Methoden sinnvoll sind:

  • Globale / Hilfsmethoden
  • Abfrageergebnisse von einer Datenmodellklasse abrufen (SP aufrufen)

Verwenden Sie sie nur, wo es angebracht ist.

  1. Wenn Sie feststellen, dass Sie dieselben Methoden in mehrere Objekte kopieren, sollten Sie die Methode statisch machen, damit Sie DRY folgen können.
  2. Verwenden Sie statische Methoden, wenn Sie keine Instanz eines Objekts benötigen (Sie arbeiten nicht an den Instanzvariablen des Objekts).

Befinden sich viele Ihrer Daten außerhalb von Objekten und werden sie über statische Methoden bearbeitet, ist Ihr Code nicht objektorientiert und kann schwierig zu warten sein.

Kodierer
quelle
1

Statisch und privat sind tatsächlich orthogonal: Eine Methode kann statisch oder privat oder keine oder beides sein.

Statisch oder nicht statisch (auch als "Instanzmethoden" bezeichnet) gibt an, ob die Methode für die Klasse selbst (statisch) oder für eine bestimmte Instanz (nicht statisch) ausgeführt wird. Abhängig von der Sprache können Sie eine statische Methode über eine Instanz aufrufen, aber Sie können niemals über eine statische Methode auf die Instanz zugreifen (was auch impliziert, dass Sie innerhalb einer statischen Methode keine nicht statischen Methoden aufrufen können, einfach weil Sie keine haben thisObjekt). Verwenden Sie statische Methoden, um Verhalten zu implementieren, das konzeptionell mit der Klasse verknüpft ist, jedoch nicht an eine bestimmte Instanz gebunden ist. Ein weiteres Szenario, in dem Sie möglicherweise statische Methoden verwenden möchten, besteht darin, dass Sie eine Funktion für zwei Instanzen einer Klasse haben und keiner der Operanden einen privilegierten Status verdient - beispielsweise unter der Annahme, dass Sie eine Klasse habenVector, und Sie möchten Addition implementieren; Ihre Additionsmethode könnte als aufgerufen werden a.Add(b), ist aber Vector.Add(a, b)wahrscheinlich sinnvoller.

Bei Private vs. Public geht es um die Sichtbarkeit der Methode. Auf private Methoden kann nur innerhalb des eigenen Bereichs der Klasse zugegriffen werden, während auf öffentliche Methoden von überall aus zugegriffen werden kann. Die wichtigste Verwendung hierfür ist die Kapselung: Indem Sie nur die Methoden und Eigenschaften öffentlich machen, die der Rest des Codes für die Kommunikation mit Ihrer Klasse unbedingt benötigt, begrenzen Sie die Punkte, an denen externer Code Probleme verursachen kann, und Sie verhindern Probleme im Code Ihre Klasse von Blutungen in den Rest des Projekts.

Also Faustregel:

  • machen Sie alle Member-Funktionen privat, mit Ausnahme derer, die von außerhalb der Klasse aufgerufen werden müssen
  • Alle Methoden zu Instanzmethoden machen, es sei denn, sie sind sinnvoll, auch wenn keine Instanz der Klasse vorhanden ist
tdammers
quelle
0

Ich verwende statische Methoden in C ++ und C # für Utility-Klassen, Klassen ohne Instanzdaten, nur eine Möglichkeit, eine Sammlung nützlicher, verwandter Methoden zu bündeln.

int count1 = DBUtil::GetCountOfSlackerEmployees();
int count2 = DBUtil::GetCountOfEmployedSlackers();
Chris O.
quelle
0

Angenommen, Sie sprechen von C ++ (haben Sie nicht gesagt) und Sie haben die richtigen Begriffe (dh Sie meinen nicht Member-Funktionen / Methoden):

Sogar eine private Member-Funktion muss noch im Header deklariert werden, was bedeutet, dass sie tatsächlich Teil der API und der ABI der Klasse wird, obwohl der Benutzer sie nicht aufrufen kann. Wenn Sie eine private Mitgliedsfunktion hinzufügen, ändern oder löschen, erzwingen Sie die Neukompilierung aller abhängigen Klassen (der Header hat sich geändert, make kann es nicht besser wissen). Wenn Sie dies in einer Bibliothek tun, müssen Sie die Kompatibilität für die verwendete Anwendung berücksichtigen es.

Auf der anderen Seite erhalten statische Funktionen mit Dateibereichen kein öffentliches Symbol, sodass Sie sie nach Belieben hinzufügen, ändern oder löschen können, ohne dass die Kompilierungseinheit davon betroffen ist.

Jan Hudec
quelle
0

In der Regel benötigen Sie eine statische Hauptleitung als Einstiegspunkt für Ihr Programm. Das könnte irgendwie wichtig sein.

Wyatt Barnett
quelle
0

Für eine statische Funktion (und für diesen Begriff gibt es in verschiedenen Sprachen unterschiedliche Bedeutungen) ist kein Status erforderlich, der zwischen den Aufrufen beibehalten wird. Wenn es konzeptionell eng mit dem verknüpft ist, was eine Klasse tut, machen Sie sie zu einer Klassenfunktion (wie bei einer Klasse, die kein Objekt ist), oder, wenn nicht, machen Sie sie zu einer globalen Funktion (oder einer Funktion auf Modulebene, was auch immer). Es gehört nicht zu einem Objekt, wenn es den Objektstatus nicht benötigt.

Wenn Sie die ganze Zeit einen Zustand übergeben, ist dies keine zustandslose Funktion, sondern Sie erstellen lediglich eine zustandsbehaftete Funktion mit zustandsloser Syntax. In diesem Fall gehört es wahrscheinlich zum aufrufenden Objekt, oder es wird ein Refactoring angezeigt, um den Status und das Verhalten besser auszurichten.

kylben
quelle
0

msgstr "warum nicht stattdessen alle privaten Mitgliedsfunktionen durch statische Funktionen ersetzen?"

... weil ein privates Mitglied auf Instanzdaten zugreifen kann, während dies nur durch Aufrufe innerhalb anderer Mitgliederfunktionen möglich ist. Die statische Funktion kann privat sein, kann aber eine Instanz der Klasse nur ändern oder referenzieren, wenn die Instanz als Parameter übergeben wird.

jheriko
quelle
0

Es ist schon komisch, dass noch niemand eine gute Antwort geben konnte. Ich bin mir auch nicht sicher, ob das so ist. Sie sollten es wahrscheinlich als Hinweis nehmen, dass sie so wenig wie möglich verwendet werden sollten. Sie sind immerhin eher prozedural als OOP.

Hier noch einige Beispiele:

In Obj-C, wo sie als Klassenmethoden bezeichnet werden, werden sie häufig als Zuordnungswrapper verwendet, in denen das Objekt vor der Rückgabe in den Referenzzählpool gestellt wird.

Ein weiteres Beispiel von Obj-C ist das Registrieren einer neuen Klasse in einer Klassensammlung. Angenommen, Sie haben eine Reihe von Klassen, die jeweils einen Dateityp verarbeiten. Wenn Sie eine neue Klasse für einen neuen Dateityp erstellen, können Sie diese mithilfe einer statischen Methode in der Klasse, die den Dateityp bestimmt, in der Auflistung (einer globalen Variablen) registrieren.

In C ++ kann ich mir auch vorstellen, Fehler leise abzufangen. Ihre Konstruktorfunktion kann nur durch Auslösen einer Ausnahme fehlschlagen. Sie können eine Fehlerinstanzvariable festlegen, dies ist jedoch nicht immer angemessen. Stattdessen können Sie die Teile, die möglicherweise fehlerhaft sind, in einem statischen Wrapper ausführen und dann das neue Objekt zuweisen und zurückgeben oder NULL bei einem Fehler.

Per Johansson
quelle
0

Angenommen, Sie möchten den Sinus von etwas berechnen.

Ohne statische:

Math math = new Math()
double y = math.sin(x)

Mit statischen:

double y = Math.sin(x)

Es macht keinen Sinn, sinnicht statisch zu machen . Es ist zustandslos und verarbeitet nur die Eingabe.

Statische Funktionen sind nicht an ein bestimmtes Objekt gebunden. Es handelt sich um "allgemeine" Funktionen, die unabhängig vom internen Zustand des Objekts sind.

dagnelies
quelle
Statische Methoden sind nicht "garantiert zustandslos". Sie können zwar keine Instanzdaten verwenden, haben aber auch Zugriff auf einen bestimmten Status (nämlich statische Member, sowohl der Klasse, zu der die statische Methode gehört, als auch eines anderen global sichtbaren Status, z. B. der statischen Variablen anderer Klassen).
@delnan: stimmt ... du hast recht. Lassen Sie mich das jetzt korrigieren.
dagnelies
Ohne statisch: x.sin(). Ihre Antwort geht davon aus, dass Sünde eine Funktion von "Mathe" sein sollte, wohingegen es sich eindeutig um ein Double handelt.
AjahnCharles
0

Ein bisschen spät, aber ich möchte versuchen, eine genaue Definition zu erstellen: Statische Funktionen sind Funktionen, die nicht auf Instanzeigenschaften / Methoden der enthaltenden Klasse verweisen oder können.

In einigen Sprachen, wie C #, können statische Felder oder Eigenschaften in statischen Klassen vorhanden sein. Daher ist es nicht richtig zu sagen, dass sie nicht für den Status verwendet werden. Eine statische Funktion verwendet möglicherweise den statischen (globalen) Status.

Grundsätzlich läuft es auf Folgendes hinaus: Statische Funktionen sind wie alle statischen nützlich, wenn es sinnvoll ist, dass sie immer verfügbar sind, ohne von nicht statischen Instanzen abhängig zu sein.

Hilfsfunktionen sind wie mathematische Funktionen ein häufiges Beispiel, aber es gibt auch andere.

Wenn die von Ihnen erstellte Klasse erfordert, dass die Daten unveränderlich sind, ist es möglicherweise sinnvoll, statische Funktionen zu erstellen, die eine Instanz aufnehmen und eine neue Instanz übergeben, da die Instanz nicht geändert werden kann (oder sollte). Beispielsweise können Zeichenfolgenklassen statische Funktionen haben, die eine Zeichenfolge (oder 2 oder mehr) aufnehmen und eine neue Zeichenfolge zurückgeben.

Ein weiterer Grund könnte sein, dass es eine Klasse gibt, die einen globalen Status oder Daten irgendeiner Art beibehält. Möglicherweise gibt es statische Funktionen, die mit den statischen Eigenschaften oder Feldern in dieser statischen Klasse arbeiten.

Bob
quelle
0

Ich möchte auf eine andere Verwendung von static f () hinweisen.

http://www.parashift.com/c++-faq/named-ctor-idiom.html

Fazit: Mit staticFunktionen können Sie "Named Constructors" erstellen, dh Sie benennen Ihre statische Funktion mit einem geeigneten und selbstdokumentierenden Namen, und diese statische Funktion ruft einen der Konstruktoren auf (da Konstruktoren identische Namen haben und Sie einen haben können) Viele von ihnen, es wird schwierig, zwischen ihnen zu unterscheiden).

newprint
quelle