Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Frage zur Typdeklaration (https://www.delphipraxis.net/170112-frage-zur-typdeklaration.html)

Jonas Shinaniganz 31. Aug 2012 10:32

Delphi-Version: 5

Frage zur Typdeklaration
 
In den Referenzen von emba steht etwas zu den Typdeklarationen
http://docwiki.embarcadero.com/RADSt...Typdeklaration


Zitat:

Die Typdeklaration selbst liegt nicht im Gültigkeitsbereich des Typbezeichners (dies gilt allerdings nicht für Zeigertypen). Aus diesem Grund kann beispielsweise ein Record-Typ definiert werden, der sich selbst rekursiv verwendet.

Wenn Sie einen Typ deklarieren, der mit einem vorhandenen Typ identisch ist, behandelt der Compiler den neuen Typbezeichner als Alias für den alten. In den Deklarationen
Wie ist der Gültigkeitsbereich eines Typbezeichners zu verstehen?

Könnt Ihr mir vielleicht noch ein Beispiel geben, wann man sinnvoller Weise soetwas macht:

Delphi-Quellcode:
type newTypeName = type KnownType
anstelle von dem gewohnten

Delphi-Quellcode:
type newTypeName = KnownType
Leider verstehe Ich nicht vollständig oder nur zum Teil worum es geht.

Vielen Dank im Vorraus! :thumb:

himitsu 31. Aug 2012 11:06

AW: Frage zur Typdeklaration
 
Delphi-Quellcode:
type
  newTypeName = KnownType;
Dieses legt nur einen Alias an, aber der Typ selbst wird nicht verändert.
TypeInfo(newTypeName) gibt also die Typinfo von KnownType zurück.

Delphi-Quellcode:
type
  newTypeName = type KnownType;
Das erstelle einen neuen und eigenständigen Typen an.

Der Compiler kann dadurch z.B. zwischen diesen Typen unterscheiden-

z.B.
Delphi-Quellcode:
procadure Xyz(var i: newTypeName);
will unbedingt genau diesen Typen.
Wurde es ohne "type" deklariert, dann kann man auch KnownType übergeben, da beide "Typen" ja identisch sind.

Gleiches gilt z.B. auch für überladene Methoden, wo man zwei Versionen erstellen könnte, welche jeweils einen der beiden Typen entgegennehmen ... vorausgesetzt die Typen sind unterscheidbar, also mit "type" deklariert.

Gleiches gilt auch für

Delphi-Quellcode:
type
  TNewClass1 = TMyClass; // Alias (alles typmäßig und inhaltlich identisch)
  TNewClass2 = type TMyClass; // neuer Typ, welcher aber inhaltlich identisch zu TMyClass ist
  TNewClass3 = class(KnownType); // abgeleitete Klasse

Uwe Raabe 31. Aug 2012 11:10

AW: Frage zur Typdeklaration
 
Zitat:

Die Typdeklaration selbst liegt nicht im Gültigkeitsbereich des Typbezeichners (dies gilt allerdings nicht für Zeigertypen). Aus diesem Grund kann beispielsweise ein Record-Typ definiert werden, der sich selbst rekursiv verwendet.
Das ist schlichtweg falsch übersetzt! Die Englische Hilfe sagt nämlich

Zitat:

A type identifier's scope doesn't include the type declaration itself (except for pointer types). So you cannot, for example, define a record type that uses itself recursively.

himitsu 31. Aug 2012 12:16

AW: Frage zur Typdeklaration
 
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;

Jonas Shinaniganz 31. Aug 2012 12:30

AW: Frage zur Typdeklaration
 
Okay, Ich könnte also auch einen Pointer-Array auf den Record in dem Record erstellen.

Dann werden Pointer verwendet und deswegen findet keine Rekursion statt, weil die Speichergröße des Records bei einem Pointer auf den Record nicht von Bedeutung ist:



Delphi-Quellcode:
type
  PMyRecord = ^TMyRecord; // geht ... erklärung siehe oben
  TMyRecord = record

jkl: array of ^TMyRecord;

// oder

mno: array[0..5] of PMyRecord;
Mit "Gültigkeitsbereich des Typbezeichners" ist also dessen Type-Block gemeint?


Alle Zeitangaben in WEZ +1. Es ist jetzt 05:42 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz