Hallo Hagen,
Zitat von
negaH:
deine Überprüfung auf zirkuläre Referenzen ist ebenfalls nicht 100%'tig sicher.
Ich bin mir nicht ganz sicher, welche Lösung Du hier ansprichst. Weder mein Code prüft soetwas ab noch sprach ich zirkuläre Hierarchien in der Vererbung an. Mein Beispiel aus der Funktion
TakeIsClassForARide sollte lediglich
unglückliche willkürliche Daten Repräsentieren. Den Fall, bei dem die eingangs gewählte zu überprüfende Referenz
zufällig auf
willkürliche Daten verweist (zB als "Rückstände" auf dem Stack). Einer der schlechtesten solche Fälle wären hierbei Daten sie -rein zufällig- so beschaffen sein
könnten, dass Dein Code sie als zyklisch interpretiert und in einer Endlosschleife zu keinem Ergebnis kommt.
Auch mein Vorschlag könnte zufällige Daten missinterpretieren (also
True zurückgeben obgleich hinter einem Datenbereich kein Objekt existiert), aber auch im worst-case nicht zu einer Endlosschleife führen.
Hast Du zu solchen Daten eine bessere Idee?
Darüber hinaus sprach ich zirkuläre Referenzen im Zusammenhang mit Interfaces an, konkret: die von Delphi implementierten Referenzzählung. Auch hier ging es weder um die Vererbungshierarchie (auf die bei Interfaces wohl auch eher selten geprüft wird, obgleich dies möglich ist) noch auf eventuelle Zyklen in ihr sondern um das Problem von "verhakten Clustern" von Objekten, die gegenseitig ihre Referenzen halten und in anderen Umegbungen nur mit einem Garbage Collector aufgelöst werden konnten.
Zitat von
negaH:
1.) in der
RTTI/
VMT ist selber ein Feld das als vmtSelfPtr bezeichnet wird. Eine gültige Klasse muß in diesem Feld auf sich selber zeigen.
Und eben genau diesen Ansatz verfolgt mein obiger Code.
Zitat von
negaH:
2.) eine gültige Klasse sollte immer im Codesegment gespeichert werden. Bis auf einem Ausnahme, meine eigene Testimplementierung, kenne ich keinen Delphi Source der dynamisch Klassen zur Laufzeit konstruiert.
Ich habe zwar an Lösungen dieser Art gearbeitet, konnte letztlich aber doch jedes Problem mit
OOP-Patterns oder Code-Generation lösen. Ich glaube deshalb ebenfalls, dass diese Fall vernachlässigt werden kann.
Zitat von
negaH:
3.) man kann über alle Typ Information der Anwendung und seiner geladenen Module iterieren.
Dieser Ansatz klingt sehr interessant: Es könnte mit
TObject.ClassType geprüft werden, ob eine gültige Klassenreferenz in der
RTTI abgelegt worden ist. Siehst Du hier in Kombination mit der Selbstreferenz noch ein Problem? Die Warhscheinlichkeit, dass bei zufälligem Speicher die Selbst-Referenz identisch ist (bei absolut zufälligen Daten) mit der Klasse selbst, liegt bei
1/2^32. Multipliziert mit der Wahrscheinlichkeit
n/2^32, dass es sich bei der Wert um eine der
n gültigen Klassen handelt, ergibt sich nach diesem Ansatz eine Wahrscheinlichkeit von
n/2^64. Geht man von weiterhin weniger als 16000 Klassen aus, liegt die Wahrscheinlichkeit einer Fehlinterpretation zufälliger Daten folglich bei weniger als
1/2^50.
Die anderen Fälle sollten bei den bisherigen Betrachtungen als ausgeschlossen gelten.
Für diesen Ansatz müsste jedoch sichergestellt werden, dass die
TypeInfo/TypeData jeder Klasse zugänglich ist. Bisher habe ich Registraturen (zB für ein dynamisches Factory-Pattern) ähnlich der Funktion
RegisterClass händisch implementiert. Kannst Du einmal zeigen, wie man über alle
RTTI aller Datentypen iterieren kann?