Einzelnen Beitrag anzeigen

Medium

Registriert seit: 23. Jan 2008
3.679 Beiträge
 
Delphi 2007 Enterprise
 
#15

AW: Zugriff auf procedure und funktionen nicht instanziierter Klassen / Objekte

  Alt 12. Feb 2013, 00:06
Der Hintergrund ist folgender: Der Code jeder Klasse besteht immer. Eine Klasse ist im Speicher nichts weiter, als ein Stück Feld-Definitionen für den Fall der Instanziierung, und ein Stück, in dem alle Methoden inkl. deren Code steht. Eine Instanz bekommt NICHT je ihre ganz eigene Kopie des Codes, sondern verweist immer nur auf die Speicherstelle, an der die Klassendefinition sie stehen hat. (Bzw. die jeweilige Elternklasse, oder es wird die VMT bemüht wenn es um virtuelle Methoden geht.) Der Code ist ab Programmstart einfach IMMER da. Die Felder auf die ggf. zugegriffen wird, sind es jedoch nicht.
Weist man also einer Variablen eine Instanz zu und zerstört diese ohne "nillen", so hat man wunderbar nachher Zugriff auf die Methoden, selbst wenn der Speicher der Instanz längst überschrieben wurde. Der Compiler weiss ja von welchem Typ die Referenz ist, und verweist munter auf die jeweiligen Stellen im Code-Segment, völlig egal ob da eine Instanz ist oder nicht.

Technisch gesehen ist dies sogar nichtmals ein Fehler, da die Methoden ja da sind! Da man (der Compiler) nicht immer 100%ig wissen kann, ob in diesen auf Felder zugegriffen wird, die möglicherweise nicht existieren, geht das auch durch den Compiler. Im günstigsten Fall mit Warnung, aber an und für sich ist da aus technischer Sicht nichts falsch dran. Man muss halt aufpassen. Und ja, das ist in anderen Sprachen auch so, wenn gleich einige solche Dinge besser erkennen können, und ggf. gleich ganz die Kompilierung untersagen. Zwingend ist das nicht.

Statische Methoden sind unter der Haube fast mit "normalen" identisch. Hier sagt man dem Compiler nur explizit: Wenn das hier aufgerufen wird, stelle mir bitte sicher, dass ich nur auf Dinge zugreife, die bereits mit der nackten Klassendeklaration in Existenz gerufen wurden! (Also andere statische Methoden für die das sicher gestellt wurde, und Klassenvariablen.) (Zudem lassen diese sich dann über den Namespace der Klasse aufrufen, nicht (nur) über eine Instanz-Referenz.) Ansonsten stehen die genau so im Codesegment wie alles andere auch. (Und, Spezialfall Delphi, "self" wird anders behandelt.)

TL;DR: Der Code ist immer da, und steht genau ein Mal pro Klasse im Speicher (egal wie viele Instanzen). Er wird immer nur von dieser einen Stelle aus aufgerufen, der Compiler ist dafür verantwortlich. Eine Instanz braucht es für den blanken Aufruf nicht, der Code ist schließlich vorhanden. Manche Sprachen prüfen sowas strikter ab, es ist aber nur ein formaler/semantischer Fehler - kein technischer/syntaktischer. Manche stellen sowas in die Verantwortung des Programmierers (und warnen ggf.), andere versuchen das ganz zu unterbinden (wodurch manche Hacks allerdings auch unmöglich werden). Delphi gehört zu ersterem, und das ist völlig in Ordnung.
"When one person suffers from a delusion, it is called insanity. When a million people suffer from a delusion, it is called religion." (Richard Dawkins)

Geändert von Medium (12. Feb 2013 um 00:09 Uhr)
  Mit Zitat antworten Zitat