Oder sagen wir es mal anders.
Pointertppen kann man vor der Deklaration des eigentlichen Typen deklarieren.
Delphi-Quellcode:
type
PMyType = ^TMyType; // theoretisch würde man denken, daß TMyType noch nicht deklariert ist.
...
TMyType = irgendwas;
...
PMyType2 = ^TMyType; // sorum geht's natürlich auch noch
Ein Pointer ist immer gleich groß und der genaue Inhalt des referenzierten Types ist nicht wichtig.
Beide Typen müssen aber im selben Type-Block stehen. (das ist aber eine Einschränkung des Compilers, damit dieser sich nicht so viel merken muß und die Prüfungen, ob's den Typ wirklich gibt, sich nicht so weit ausdehnen)
Delphi-Quellcode:
type
PMyType = ^PMyType;
...
type
TMyType = irgendwas;
Das geht also nicht.
Um einen Typen verwenden zu können, muß dessen Speichergröße aber vollkommen fest stehen.
Ein Record in sich selber geht also nicht, da man sich ja noch mitten in der Typdeklaration befindet und die Größe des Records noch nicht feststeht.
Außerdem würde der Record "unendlich" groß werden, wenn er direkt in sich selber deklariert würde.
Delphi-Quellcode:
type
PMyRecord = ^TMyRecord; // geht ... erklärung siehe oben
TMyRecord = record
abc: TMyRecord; // geht nicht, da der Typ noch nicht komplett ist und außergem würde eine unendliche Rekursion entstehen
def: PMyRecord; // geht
ghi: ^TMyRecord; //geht, da es ein
jkl: array of TMyRecord; // geht nicht, da der Typ noch nicht komplett ist (die Rekursion gibt's nicht, da ein dynamisches Array ein Pointer ist)
mno: array[0..5] of TMyRecord; // geht nicht, da der Typ noch nicht komplett ist und wieder diese blöde Rekursion
end;
Bei Objekten isses was Anderes, denn das sind ja wieder Pointer.
Da bei Objekte und Interfaces einem definierten Grundtypen entsprechen (TObject/IInterface) und eine definerte Größe besitzen, kann man dafür auch eine Forwarddeklaration nutzen, womit man sie nutzen kann, noch bevor sie deklariert wurden.
Aber auch hier gilt natürlich, daß dieses im selben Type-Bolck stehen muß.
Delphi-Quellcode:
type
TMyObject = class;
TMyObject2 = class;
...
TMyObject2 = class(TIrgendwas)
property A: TMyObject;
property B: TMyObject2;
end;
...
TMyObject = class
end;