Als Antwort auf Aaronaught's Antwort auf die Frage unter:
Kann ich nicht einfach alle statischen Methoden verwenden?
Wird für eine statische Methode nicht weniger Speicher verwendet? Ich habe den Eindruck, dass jede Objektinstanz ihre eigene ausführbare Version einer nicht statischen Elementfunktion enthält.
Unabhängig davon, wie viel Overhead mit dem Aufrufen einer statischen Methode verbunden ist, unabhängig vom schlechten OO-Design und möglichen Kopfschmerzen, verbraucht sie zur Laufzeit nicht weniger Speicher?
Hier ist ein Beispiel:
Ich mache einen Vektor aus nullinitialisierten Objekten. Jedes Objekt enthält ein Datenelement (ein Dreieck aus neun Doppeln). Jedes Objekt wird nacheinander aus Daten gefüllt, die aus einer STL-Datei gelesen wurden. Es wird nur eine statische Methode benötigt. Das richtige OO-Design schreibt vor, dass eine Methode, die sich direkt mit den Daten befasst, auf jedes Objekt verteilt werden soll. Hier ist die Standard-OO-Lösung:
foreach(obj in vec) {
obj.readFromFile(fileName);
}
Jedes Objekt trägt readFromFile
den kompilierten Code neben den Daten!
Der Speicher ist in diesem Fall eher ein Problem als die Leistung, und auf einem eingeschränkten System befinden sich viele Daten.
Lösungen:
- Namespace-Methode (ideal für C ++, aber in Java nicht möglich)
- Eine statische Methode in der Klasse von obj. Ausführbarer Code wird zur Laufzeit an einem Ort gespeichert. Das Aufrufen der Methode ist mit einem geringen Aufwand verbunden.
- Eine übergeordnete Klasse, von der obj abgeleitet ist und die die private Methode enthält
readFromFile
. Anruf mitsuper.callPrivateMethod()
welchen AnrufenreadFromFile
. Chaotisch und immer noch etwas Speicheraufwand in jedem Objekt. - Implementieren Sie
readFromFile
außerhalb des Bereichs von obj, also in der vec-Klasse oder in der aufrufenden Klasse. Dies unterbricht meiner Meinung nach die Datenkapselung.
Mir ist klar, dass für große Datenmengen ein explizites Objekt für jedes Dreieck nicht der beste Ansatz ist. Dies ist nur ein Beispiel.
quelle
Antworten:
Methoden werden auch bei virtuellen Methoden nicht auf Instanzbasis gespeichert. Sie werden an einem einzigen Speicherort gespeichert und "wissen" nur, zu welchem Objekt sie gehören, da der
this
Zeiger beim Aufrufen übergeben wird.Der einzige zusätzliche Speicher, der in C ++ benötigt wird, ist, wenn Sie virtuelle Methoden verwenden, für die ein einzelner zusätzlicher Zeiger pro Instanz erforderlich ist, um auf die virtuelle Methodentabelle zu verweisen (in Java haben Sie natürlich immer eine Basisklasse mit virtuellen Methoden
Object
, daher ist dies unvermeidlich ).Wenn es so funktionieren würde, wie Sie es beschrieben haben, wären OO-Sprachen nicht sehr beliebt! Sie können Ihren Objekten beliebig viele Methoden hinzufügen. Dies hat keinen Einfluss auf die Speichernutzung.
quelle
Das ist ziemlich kompliziert, aber ich würde "meistens nein" sagen.
quelle
Eine Methode sollte "statisch" sein (viele Sprachen verwenden den Begriff "Klassenmethode", was viel besser ist), wenn sie sich nicht auf eine Instanz der Klasse bezieht. Es sollte eine Instanzmethode sein, wenn sie sich auf eine Instanz der Klasse bezieht.
Es ist eine sehr, sehr, sehr schlechte Idee, eine Entwurfsentscheidung zu treffen, die auf der vagen Möglichkeit einer Speichereinsparung anstelle der richtigen Verwendung von Klassenmethoden und Instanzmethoden basiert.
quelle
Im Prinzip gibt es nur eine Kopie des Codes, unabhängig davon, ob es sich um statische Elementfunktionen handelt oder nicht:
Die Verwendung einer statischen oder einer nicht statischen Funktion ändert daher nicht den Speicherbedarf.
In Wirklichkeit gibt es einen sehr sehr kleinen Unterschied, sowohl im generierten Code als auch im Speicher, der während der Ausführungszeit der Funktion auf dem Stapel verbraucht wird:
Dies ist jedoch wirklich vernachlässigbar: Wir sprechen mehr oder weniger von einer oder zwei Maschinenanweisungen im Vergleich zum vollständigen Code. Es ist also definitiv kein Grund zur Sorge.
Die Stapelverbrauchsdifferenz zur Laufzeit ist auf den Zeitpunkt der Ausführung der Funktion und auf die Größe eines Zeigers begrenzt. Dies ist auch vernachlässigbar, es sei denn, Sie denken an eine Funktion, die sehr oft (mehrere Millionen Mal) rekursiv aufgerufen wird.
Abschließend teile ich die Meinung von gnasher729 voll und ganz : Vorzeitige Optimierung ist die Wurzel allen Übels. Wenn die Funktion vom Objekt unabhängig ist, machen Sie sie statisch und das sollte das einzige Kriterium sein.
quelle
this
, wenn er nicht in der Funktion verwendet wird. In Java könnte JIT dies wahrscheinlich tun.Es ist einfach, sich auf Dinge wie die Optimierung der Speichernutzung oder die Reduzierung von Codezeilen zu konzentrieren, aber wenn Sie anfangen, Programme zu warten, die von Benutzern verwendet / unterbrochen werden, und andere Programmierer Funktionen hinzufügen ... und möglicherweise Fehler einführen ... nicht, dass Ihr ursprüngliches Programm Möglicherweise gibt es Fehler, die es nach dem Testen geschafft haben. Sie werden feststellen, dass es möglicherweise wichtiger ist, sich auf die Lesbarkeit / Wartbarkeit des Codes zu konzentrieren. Ich könnte ein Hochgeschwindigkeits-Bit-Array erstellen, um eine Reihe von Datenpunkten zu verfolgen, aber wenn ich dieses Bit-Array nicht in ein Objekt mit verständlichen Zugriffsmethoden einwickle, wird der nächste Programmierer, der diesen Code berührt, ihn wahrscheinlich nicht verwenden, ersetzen oder eine abscheuliche Hexerei betreiben .
quelle