4. Typen und Datenstrukturen | ||||||
|
||||||
4.5 Überwachte Typen ("Controlled Types")
Beispiel:
Der Nutzer kann die vordefinierten Prozeduren benutzen oder geeignet überladen. Diese Prozeduren heißen "Initialize", "Finalize" und "Adjust" und haben das Objekt des überwachten Typs als Parameter mit dem Modus "in out". Sie werden automatisch an verschiedenen Stellen im Programm aufgerufen. Das Beispiel zeigt den automatischen Aufruf der Prozeduren an verschiedenen Stellen eines Programmfragments. "T" sei dabei ein überwachter Typ. Nachdem "A" deklariert worden ist und jede normale Initialisierung ausgeführt wurde, wird die Prozedur "Initialize" aufgerufen. Bei einer Deklaration mit expliziter Vorbesetzung wie bei "B" wird dagegen "Adjust" aufgerufen. Bei der Zuweisung wird zuerst "Finalize" aufgerufen, um das alte Objekt zu beenden, damit es überschrieben werden kann, dann wird die Kopie angefertigt und schließlich wird "Adjust" aufgerufen um alles auszuführen, was für die korrekte Besetzung der neuen Kopie nötig ist. Am Ende des Blockes wird "Finalize" noch einmal aufgerufen, bevor die Objekte beendet werden. Zu beachten ist, daß der Nutzer die Aufrufe an die drei Prozeduren nicht explizit zu schreiben braucht. Die Aufrufe werden automatisch beim Übersetzen erzeugt. Im Falle verschachtelter Strukturen bei denen innere Komponenten "controlled" sind, besagen die Regeln, daß zunächst diese inneren Komponenten initialisiert und angepaßt werden, bevor das Objekt als Ganzes behandelt wird. Bei der Beendigung läuft alles in umgekehrter Reihenfolge ab. Um einen überwachten Typ zu verwenden, muß er von einem von zwei erweiterbaren Typen aus dem Paket "Ada.Finalization" abgeleitet werden. Die Spezifikation ist:
Es werden zwei unterschiedliche abstrakte Typen für nicht limitierte und für limitierte Typen angeboten. Für limitierte Typen existiert keine Prozedur "Adjust", da Zuweisungen für limitierte Typen nicht definiert sind. Obwohl die Typen "Controlled" und "Limited_Controlled" abstrakt sind, sind die Prozeduren "Initialize", "Adjust" und "Finalize" nicht abstrakt. Sie haben alle einen leeren Anweisungsteil (begin null; end;), tun also nichts, was in vielen Fällen genau das ist, was der Nutzer möchte. Er braucht dann diese Prozeduren für seine von "Controlled" oder "Limited_Controlled" abgeleiteten Typen nicht zu überschreiben. Eine typische Deklaration eines überwachten Typs sieht so aus: type T is new Ada.Finalization.Controlled with record... Der Anwender muß dann neue Versionen für die Prozeduren schreiben, die er benötigt (also nicht unbedingt für alle drei). Die Möglichkeiten der überwachten Typen bieten dem Programmierer die Kontrolle über Speicherressourcen. Im besonderen erlauben sie die Garantie eines sauberen Aufräumens, bevor ein Objekt für immer unzugreifbar wird. Die Möglichkeit einer automatischen Beendigung ist extrem wichtig, besonders wenn man berücksichtigt, daß ein Gültigkeitsbereich auf viele verschiedene Arten verlassen werden kann (Ausnahme, Exit-Anweisung, Return-Anweisung, Abort-Anweisung, asynchroner Prozesswechsel etc). In all diesen Fällen wird automatisch "Finalize" für alle in dem Gültigkeitsbereich deklarierten Objekte eines überwachten Typs aufgerufen. In vielen Fällen werden überwachte Typen mehr aus Gründen der Sicherheit und Zuverlässigkeit eingesetzt und sind nicht unbedingt sichtbarer Teil der Spezifikation. Die meisten Benutzer einer Abstraktion brauchen nicht zu wissen, ob die Implementierung überwachte Typen benutzt oder nicht. In diesem Beispiel wird z. B. anhand der Nummer die Reihenfolge der Erstellung von zwei Objekten ermittelt. obmieinu.ads
|
||||||
|