Retrouvez cet article dans : Linux Magazine 84
1 package Polygones is
2 type Point is
3 record
4 x: Float := 0.0 ;
5 y: Float := 0.0 ;
6 end record ;
7 function To_String(p: in Point) return String ;
8 type TabPoints is array (Positive range <>) of Point ;
9 type TabPoints_Ptr is access all TabPoints ;
10 type Polygone is tagged private ;
11 procedure Init(p : in out Polygone ;
12 taille: in Natural) ;
13 procedure Detruire(p: in out Polygone) ;
14 function To_String(p: in Polygone’Class) return string ;
15 private
16 type Polygone is tagged
17 record
18 pts: TabPoints_Ptr ;
19 end record ;
20 end Polygones ;
On commence par la déclaration d’un type représentant un point (lignes 2 à 6), suivi d’une fonction facilitant son affichage, puis d’un type tableau de points avec un type pointeur associé. Notre type 1 with Text_IO ; use Text_IO ;
2 with Polygones ; use Polygones ;
3 procedure Test_Poly is
4 p1: Polygone ;
5 p2: Polygone ;
6 begin
7 p1.Init(2) ;
8 Put_Line(p1.To_String) ;
9 p2 := p1 ;
10 p2.Detruire ;
11 Put_Line(p1.To_String) ;
12 end Test_Poly ;
Comme vous vous en doutez, la procédure $ gnatmake test_poly && ./test_poly gcc -c test_poly.adb gcc -c polygones.adb gnatbind -x test_poly.ali gnatlink test_poly.ali [ ( 0.00000E+00, 0.00000E+00 ) -> ( 0.00000E+00, 0.00000E+00 ) ] raised CONSTRAINT_ERROR : polygones.adb:47 index check failedPas de chance : le programme plante par la levée de l’exception
Les types limités
C’est là qu’interviennent les types limités. Un type enregistrement qualifié par le mot-clef... 10 type Polygone is tagged limited private ;
... 16 type Polygone is tagged limited 17 record ...Comme vous pouvez le constater, les modifications sont réellement mineures : simplement l’ajout de
1 procedure Test is
2 type T is limited
3 record
4 a: Integer ;
5 end record ;
6 t1: T ;
7 t2: T ;
8 begin
9 t1.a := 1 ; -- OK
10 t1 := t2 ; -- erreur !
11 end Test ;
Toutefois, dans la pratique, ce genre de déclarations présente rarement un grand intérêt.
Types contrôlés
Les restrictions imposées par le qualificatif 1 with Ada.Finalization ;
2 package Polygones is
3 type Point is
4 record
5 x: Float := 0.0 ;
6 y: Float := 0.0 ;
7 end record ;
8 function To_String(p: in Point) return String ;
9 type TabPoints is array (Positive range <>) of Point ;
10 type TabPoints_Ptr is access all TabPoints ;
11 type Polygone is tagged private ;
12 procedure Init(p : in out Polygone ;
13 taille: in Natural) ;
14 procedure Detruire(p: in out Polygone) ;
15 procedure Def_Point(poly: in out Polygone ;
16 ind : in Positive ;
17 pt : in Point) ;
18 procedure Initialize(p: in out Polygone) ;
19 procedure Adjust(p: in out Polygone) ;
20 procedure Finalize(p: in out Polygone) ;
21 function To_String(p: in Polygone’Class) return string ;
22 private
23 type Polygone is new Ada.Finalization.Controlled with
24 record
25 pts: TabPoints_Ptr ;
26 end record ;
27 end Polygones ;
Les trois procédures surdéfinies apparaissent lignes 18 à 20, tandis que la ligne 23 réalise la dérivation du type 45 procedure Initialize(p: in out Polygone) is
46 begin
47 Put_Line("Initialize " & Integer_Address’Image(To_Integer(p’Address))) ;
48 end Initialize ;
La procédure 62 procedure Finalize(p: in out Polygone) is
63 begin
64 Put_Line("Finalize " & Integer_Address’Image(To_Integer(p’Address))) ;
65 if p.pts /= null
66 then
67 Free(p.pts) ;
68 end if ;
69 end Finalize ;
À l’inverse, la procédure 50 procedure Adjust(p: in out Polygone) is
51 ptr: TabPoints_Ptr ;
52 begin
53 Put_Line("Adjust " & Integer_Address’Image(To_Integer(p’Address))) ;
54 if p.pts /= null
55 then
56 ptr := new TabPoints(p.pts.all’Range) ;
57 ptr.all := p.pts.all ;
58 p.pts := ptr ;
59 end if ;
60 end Adjust ;
Enfin, - 1. L’instance cible de l’affectation (le membre de gauche de l’opérateur
:=) est finalisée, sans pour autant être détruite :Finalize()est invoquée. - 2. Ensuite les membres sont copiés de la source dans la destination.
- 3. Puis la procédure
Adjust()est invoquée, afin d’ajuster éventuellement le résultat de la copie.
1 with Text_IO ; use Text_IO ;
2 with Polygones ; use Polygones ;
3 procedure Test_Fin_Poly is
4 p1: Polygone ;
5 p2: Polygone ;
6 begin
7 Put_Line("--- Début”) ;
8 p1.Init(2) ;
9 p1.Def_Point(1, (1.0, 2.0)) ;
10 p1.Def_Point(2, (11.0, 22.0)) ;
11 Put_Line(p1.To_String) ;
12 Put_Line(p2.To_String) ;
13 Put_Line(“--- p2 := p1...”) ;
14 p2 := p1 ;
15 Put_Line(“--- p1.Detruire...”) ;
16 p1.Detruire ;
17 Put_Line(p1.To_String) ;
18 Put_Line(p2.To_String) ;
19 Put_Line(“--- Fin”) ;
20 end Test_Fin_Poly ;
Voici ce que cela donne à l’exécution :
$ ./test_fin_poly Initialize 3213236128 Initialize 3213236108 --- Début [ ( 1.00000E+00, 2.00000E+00 ) -> ( 1.10000E+01, 2.20000E+01 ) ] [] --- p2 := p1... Finalize 3213236108 Adjust 3213236108 --- p1.Detruire... [] [ ( 1.00000E+00, 2.00000E+00 ) -> ( 1.10000E+01, 2.20000E+01 ) ] --- Fin Finalize 3213236108 Finalize 3213236128Vous pouvez constater que la création des instances
Conclusion
Voilà pour cette présentation des types limités et contrôlés. La prochaine fois, nous aborderons les facilités offertes par Ada pour s’interfacer avec d’autres langages de programmation, notamment les langages C et C++, mais également ce bon vieux Fortran.Retrouvez cet article dans : Linux Magazine 84





Donnez votre avis
Vous devez avoir ouvert une session pour écrire un commentaire.