5. Sprachelemente / Operatoren
 
zurück
5.1.4.2 Aggregate für Verbunde


Jeder Komponente eines Verbunds kann entweder über den Namen oder über eine Positionsangabe ein Wert zugeordnet werden. Die Komponenten eines Verbunds haben in der Regel unterschiedliche Typen. Wenn eine der Komponenten aus einer Reihung besteht, so muß diese Reihung feste Indexgrenzen haben. In Aggregaten dürfen nur eingeschränkte Reihungstypen verwendet werden. (record_aggregate <BNF>)

Aggregat_fuer_Verbundtypen ::= ( Komponentenzuordnungsliste )
Komponentenzuordnungsliste ::= Komponentenzuordnung { , Komponentenzuordnung } | null record
Komponentenzuordnung ::= [ Komponentennamenliste => ] Komponentenwert
Komponentennamenliste ::= Komponentenname { | Komponentenname } | others

Ein Aggregat für Verbundtypen besteht aus einer Liste von Komponentenzuweisungen oder
aus "null record" (nur bei erweiterbaren Typen möglich).

Bei Verbundtypen können die verschiedenen Zuordnungsarten auch kombiniert werden. So kann man z. B. einigen Komponenten nach Position Werte zuordnen, einigen nach Namen und den restlichen mit "Others". Die Zuordnungsart "Others" ist die einzige oder letzte Position in einem Aggregat.

Hierbei ist zu beachten, daß bei der Kombination der Zuordnungsarten nach Position und nach Namen die Zuordnungen nach Position als erstes erscheinen müssen, diese sind dann auch die ersten Komponenten im entsprechenden Typ.

Generell ist es empfehlenswert, allen Komponenten die Werte nach Namen zuzuordnen.

Beispiele:

procedure Berufe is
   -- Definition fuer die folgenden Beispiele
   type Person is record
      Name : String (1..20);
      Vorname : String (1..20);
      Beruf : String (1..20);
   end record;
   Eine_Person : Person;

begin
   -- 1. Möglichkeit
   Eine_Person := ( Name => "Babbage ", Vorname => "Charles ", Beruf => "Mathematiker ");

   -- 2. Möglichkeit
   Eine_Person := ( Vorname|Beruf => " ", Name => "Babbage ");

   -- 3. Möglichkeit
   Eine_Person := ( Name => "Babbage ", others => " ");
end;

Wenn in der Definition des Verbundtyps Diskriminanten enthalten sind, so muß auch der Wert für diese angegeben werden, entweder per Name oder bei Zuordnung nach Position an erster Stelle.

Beispiel:

type Größe_Bereich is range 0..50;
type Integer_Liste is array (Größe_Bereich range <>) of Integer;
type Mein_Verbund (Größe : Größe_Bereich := 50) is record
   A : Integer_Liste( 1 .. Größe );
   B : Float;
   C : Character;
end record;
...
-- Deklaration: Diskriminante ist mit 50 vorbesetzt, somit wird für
-- MV.A Speicherplatz für eine Reihung mit 50 Integer-Zahlen reserviert:
MV : Mein_Verbund;
...
-- Die Diskriminante wird auf 20 gesetzt, es werden also nur die ersten
-- 20 Reihungen von MV.A verwendet. Ab jetzt können auch nur noch die
-- ersten 20 Reihungen angesprochen werden, ohne einen Laufzeitfehler zu
-- erhalten. Durch erneute Zuweisung eines anderen Wertes kann diese
-- Beschränkung wieder aufgehoben werden:
MV := (Größe => 20, A => (20 => 20, Others => 1), B => 0.0, C => 'A');

Voraussetzung für die Erweiterung von Verbundtypen ist ein erweiterbarer Typ (tagged type). Dieser erweiterbare Typ ist ein Verbundtyp, der selbst auch schon Komponenten enthalten kann, aber nicht muß.

Ziel der Erweiterung von Verbundtypen ist es, auf der Basis eines Verbundtyps eine Hierarchie von Verbundtypen aufbauen zu können. Diese Typen haben dann gleiche Eigenschaften und können so leicht in einen anderen Typ dieser Verbundtyphierarchie konvertiert werden.

Aggregat_für_Erweiterung_von_Verbundtypen ::=
( Vorfahre with Komponentenzuordnungsliste )

Der Vorfahre kann hierbei entweder eine Variable eines erweiterbaren Verbundtyps sein, der in der Verbundtyphierarchie über dem erweiterten Typ steht, oder aber ein Aggregat für Verbundtypen mit den entsprechenden Komponenten des übergeordneten Verbundtyps (Konvertierung in der OOP).

Die Zuordnung erfolgt, wie bei den Verbundtypen, über Position, Namen und "Others".

Beispiele:

type Punkt_Typ is tagged record
   X, Y : Integer;
end record;

type Kreis_Typ is new Punkt_Typ with record
   Radius : Integer;
end record;

type Rechteck_Typ is new Punkt_Typ with record
   X2, Y2 : Integer;
end record;
...
Punkt : Punkt_Typ;
Kreis : Kreis_Typ;
Rechteck : Rechteck_Typ;
...
Punkt := (X|Y => 100);
Kreis := (Punkt with Radius => 20);
Rechteck := (Punkt with X2|Y2 => 200);

Bei der Verwendung von Diskriminanten in einem Verbund ist zu beachten, daß - auch wenn der Vorfahre schon diese Diskriminante initialisiert hat - der Wert für diese Komponente erneut hinter dem with angegeben werden muß, und zwar mit dem Wert, der auch bei der Deklaration der Variablen verwendet wurde.

Beispiel:

type Größe_Bereich is range 0..50;
type Integer_Liste is array (Größe_Bereich range <>) of Integer;
type Mein_Erweiterbarer_Verbund (Größe : Größe_Bereich) is tagged record
   A : Integer_Liste( 1 .. Größe );
   B : Float;
   C : Character;
end record;

type Mein_Erweiterter_Verbund is new Mein_Erweiterbarer_Verbund with record
   D : Boolean;
end record;
...

-- Beide Verbunde werden mit maximaler Größe von 50 deklariert.
Erweiterbar : Mein_Erweiterbarer_Verbund(50);
Erweitert : Mein_Erweiterter_Verbund(50);
...
-- Zuweisung mit einer Größe von 50
Erweiterbar := (Größe => 50,
                A     => (20 => 20, Others => 1),
                B     => 0.0,
                C     => 'A' );
-- Zuweisung mit gleicher Größe wie bei der Deklaration der Variable 'Erweitert
Erweitert := (Erweiterbar with Größe => 50, D => True);



 
zurück
 Index   Ada Tour - Dokumentation  
© 2003 Förderverein Ada Deutschland e.V.