Рассмотренные нами ссылочные типы могут быть использованы только как средство косвенного доступа к объектам которые размещаются в области динамической памяти.
Однако, бывают случаи когда необходимо использование механизма косвенного доступа для статического объекта, то есть, необходимо иметь возможность обратиться к содержимому статического объекта используя значение ссылочного типа.
Ада (согласно стандарта Ada95) предоставляет возможность описывать статические объекты (переменные или константы) так, чтобы они являлись косвенно доступными, а также предоставляет возможность описывать ссылочные типы, так, чтобы они могли ссылаться не только на объекты размещенные в пуле динамической памяти, но и на статические объекты (которые были описаны как косвенно доступные).
В этом случае, статические объекты (переменные или константы) описываются с использованием зарезервированного слова aliased, которое указывает, что данный статический объект является косвенно доступным.
Например:
| Int_Var : aliased Integer; Int_Const : aliased constant Integer := 0; |
Чтобы получить ссылочные значения для статических объектов которые допускают использование косвенного доступа необходимо использовать атрибут 'Access.
Чтобы предоставить возможность ссылочному типу ссылаться на косвенно доступные статические объекты, ссылочный тип описывается с использованием зарезервированного слова all
или зарезервированного слова constant.
Заметим, что такие ссылочные типы называют обобщенными ссылочными типами (general access types), и они также могут быть использованы для доступа к объектам которые размещены в пуле динамической памяти.
Например:
| type Int_Var_Ptr is access all Integer; type Int_Const_Ptr is access constant Integer; |
При этом, если при описании ссылочного типа использовано зарезервированное слово all, то такой ссылочный тип предоставляет доступ который позволяет осуществлять как чтение, так и запись содержимого объекта на который ссылается значение этого ссылочного типа.
|
procedure General_Access_Demo is type Int_Var_Ptr_Type is access all Integer; A : aliased Integer; X, Y : Int_Var_Ptr_Type; begin X := A'Access; Y := new Integer; end General_Access_Demo; |
|
type Array_Type is array (Positive range < >) of aliased Integer; type Record_Type is record A_Int_Var : aliased Integer; Int_Var : Integer; end record; type Int_Var_Ptr_Type is access all Integer; |
|
package Message_Services is type Message_Code_Type is range 0..100; subtype Message is String; function Get_Message(Message_Code: Message_Code_Type) return Message; pragma Inline(Get_Message); end Message_Services; package body Message_Services is type Message_Handle is access constant Message; Message_0: aliased constant Message := "OK"; Message_1: aliased constant Message := "Up"; Message_2: aliased constant Message := "Shutdown"; Message_3: aliased constant Message := "Shutup"; . . . Message_Table: array (Message_Code_Type) of Message_Handle := (0 => Message_0'Access, 1 => Message_1'Access, 2 => Message_2'Access, 3 => Message_3'Access, . . . ); function Get_Message(Message_Code: Message_Code_Type) return Message is begin return Message_Table(Message_Code).all; end Get_Message; end Message_Services; |