Guía mínima de Ada 95 |
Pint1, Pint2 : TP_Integer; --Punteros a integer
dinámico
PPer1, PPer2 : TP_Persona; --Punteros a TPersona
dinámicos
i : integer; --Variable estática de tipo
integer
p : TPersona; --Variable estática de
tipo TPersona
Los punteros se inicializan automáticamente con el valor null. indicando que no referencian a ninguna variable.
Las variables creadas dinámicamente se pueden
inicializar en su creación:
Pint2 := new integer'(35);
PPer2 := new TPersona'("Pepe
","Pérez ","Pérez
");
Además, una variable puntero puede ser inicializada
en su declaración:
Pint : TP_Integer := new integer'(35);
Cuando la variable referenciada es un record se puede
acceder a cada campo utilizando simplemente el cualificador punto (.):
p.Nombre := PPer1.Nombre;
p.Apellido1 := PPer1.all.Apellido1; --El
.all
es inncesario
Si la variable referenciada es un array se puede
acceder a sus elementos individuales utilizando paréntesis del modo
habitual:
type TArray is array (integer
range
<>) of integer;
type TP_Array is access
TArray;
v : TP_Array := new TArray'(1,2,3,4,5);
...
i := v(3);
A continuación, se debe instanciar el procedimiento
genérico "Unchecked_Deallocation" para el tipo de dato y tipo de
puntero que se quiere liberar:
procedure Libera_Persona is new
Unchecked_Deallocation(TPersona,TP_Persona);
Ahora, se puede usar Libera_Persona para liberar
variables dinámicas de tipo TPersona referenciadas por variables
puntero de tipo TP_Persona:
Libera_Persona(PPer1);
Para que la dirección de una variable estática
pueda ser asignada a un puntero, ésta debe permitirlo en su
declaración, utilizando la palabra aliased:
p1: aliased TPersona;
La dirección de una variable declarada así
puede obtenerse mediante el atributo access:
PGPer := p1'access; --Asigna a PGPer
la dirección de p1
Se puede imponer restricción de lectura a
un puntero, de forma que no se pueda modificar el objeto al que apunta,
pudiendo entonces utilizarse para referenciar una constante, o para referenciar
una variable de forma segura, con la garantía de que no podrá
modificarse a través del puntero:
type Punt_Const_Int is access
constant integer; --Tipo de los punteros a enteros constantes
...
type Punt_Int is access all
integer; --Tipo de los punteros a variables integer (estáticos o
dinámicos)
PCI1,PCI2 : Punt_Const_Int;
Pint3 : Punt_Int;
i : aliased integer;
...
PCI1 := i'access;
Pint3 := i'access; --PCI1 y Pint3 son
alias de i
i := 3;
Pint3.all := 4; --Modifica i
PCI1.all := 5; --ERROR, no se puede modificar
i a través de PCI
PCI2 := new integer'(9); --Se puede hacer
new siempre que se inicialice
donde PNodoLista es el tipo de los punteros a objetos
de tipo NodoLista. Esto significa que debería existir una definición
para PNodoLista:
type PNodoLista is access NodoLista;
Esta definición debería estar antes
que la de NodoLista, para que sea conocida cuando se declara el campo siguiente
de éste; pero entonces NodoLista no se conocería cuando se
intenta definir PNodoLista, creándose un círculo vicioso.
La solución consiste en empezar con una declaración incompleta
de NodoLista que establezca que tal tipo va a existir, pero sin concretarlo,
cosa que debe hacerse más adelante en la misma parte del programa.
Una declaración incompleta comienza igual que una definición
completa, pero termina con un punto y coma (;) donde ésta tiene
la palabra is:
type NodoLista;
type PNodoLista is access NodoLista;
type NodoLista is record
Info: integer;
Siguiente: PNodoLista;
end record;