Christoph Karl Walter Grein
Ein hehres Prinzip guter Software-Entwicklung ist das Geheimnisprinzip (information hiding). Es besagt, dass man alles, was der Anwender nicht zu wissen braucht, verstecken soll. Auch Lady Ada liebt es, Verstecken zu spielen; sie ist ein rechter Geheimniskrämer.
with Ada.Finalization; use Ada.Finalization; package Geheimniskrämer is type Wurzel is tagged private; private type Wurzel is new Controlled with null record; procedure Initialize (Objekt: in out Wurzel); procedure Adjust (Objekt: in out Wurzel); procedure Finalize (Objekt: in out Wurzel); end Geheimniskrämer;
package Geheimniskrämer.Abgeleitet is type Etwas is tagged private; Nichts: constant Etwas; private type Etwas is new Wurzel with null record; procedure Initialize (Objekt: in out Etwas); procedure Adjust (Objekt: in out Etwas); procedure Finalize (Objekt: in out Etwas); Nichts: constant Etwas := (Wurzel with null record); end Geheimniskrämer.Abgeleitet;
Hier wird durch Ableitung vom vordefinierten Typ Ada.Finalization.Controlled eine Klasse kontrollierter Typen definiert mit dem Ursprungstyp Wurzel. Kontrolliertheit ist eine neue Ada95-Errungenschaft, die uns zusätzliche Kontrolle über die drei fundamentalen Operationen auf Objekten ermöglicht: Erzeugung, Zuweisung, Vernichtung - ihnen sind die drei Prozeduren Initialize, Adjust und Finalize zugeordnet. Die exakte Definition ist im Ada RM Kapitel 7.6 User-Defined Assignment and Finalization zu finden. Wir wollen uns das Verhalten kontrollierter Typen an Hand des folgenden einfachen Hauptprogramms einmal anschauen:
with Geheimniskrämer.Abgeleitet; use Geheimniskrämer.Abgeleitet; with Ada.Text_IO; use Ada.Text_IO; procedure Ausprobieren is Ding: Etwas; begin Put_Line ("Rumpf von Ausprobieren beginnt jetzt."); Ding := Nichts; Put_Line ("Rumpf von Ausprobieren endet jetzt."); end Ausprobieren;
Hier geschieht im wesentlichen Folgendes:
Dieser gesamte Ablauf sei hier noch einmal zusammengefasst:
Initialize gerufen für Objekt des Typs Wurzel | » | Initialisierung des Wurzel-Teils von Nichts |
Initialize gerufen für Objekt des Typs Etwas | » | Initialisierung der lokalen Variablen Ding |
Rumpf von Ausprobieren beginnt jetzt. | ||
Finalize gerufen für Objekt des Typs Etwas | » | Vor-Zuweisungsfinalisierung von Ding |
Adjust gerufen für Objekt des Typs Etwas | » | Nach-Zuweisungsausrichtung von Ding |
Rumpf von Ausprobieren endet jetzt. | ||
Finalize gerufen für Objekt des Typs Etwas | » | Ende des Gültigkeitsbereichs von Ding |
Finalize gerufen für Objekt des Typs Etwas | » | Ende des Gültigkeitsbereichs von Nichts |
Nun bekam Lady Ada neulich einen verzweifelten Brief von einem ihrer neuen Verehrer. Er sandte ihr ein kleines Programm, das er verfasst hatte, und schrieb dazu:
with Geheimniskrämer; use Geheimniskrämer; package Neuling is type Etwas is tagged private; Nichts: constant Etwas; private type Etwas is new Wurzel with null record; procedure Initialize (Objekt: in out Etwas); procedure Adjust (Objekt: in out Etwas); procedure Finalize (Objekt: in out Etwas); Nichts: constant Etwas := (Wurzel with null record); end Neuling;
with Neuling; use Neuling; with Ada.Text_IO; use Ada.Text_IO; procedure Überraschung is Ding: Etwas; begin Put_Line ("Rumpf von Überraschung beginnt jetzt."); Ding := Nichts; Put_Line ("Rumpf von Überraschung endet jetzt."); end Überraschung;
"Verehrte Lady Ada,
wie Sie in der Anlage sehen können, habe ich genau dasselbe wie Sie gemacht, allerdings mit für mich unerfahrenen Adepten gänzlich unerwartetem Ergebnis - zwar ähnlich wie oben, doch wird keine der drei Operationen für Etwas aufgerufen, sondern stets die für Wurzel. Wieso?
Um Aufklärung heischend verbleibe ich Ihr allerergebenster Diener, ..."
Eine übersetzbare und ausführbare Version des Programms ist hier ladbar.
© Copyright 2000 C.K.W. Grein |