Previous | Next | Table of Contents | Index | Program List | Copyright

15.3 Data Structures: General Access Types

The access types we saw in Chapter 14 can acquire values in only two ways: as the result of an allocator (NEW) operation or as a copy of another access value. In particular, there is no direct way to cause an access value to designate a declared variable or constant. As it happens, there are really two kinds of access types:

Here are three versions of an access type declaration:

    TYPE IntegerPointer IS ACCESS Integer;
    TYPE IntegerPointer IS ACCESS ALL Integer;
    TYPE IntegerPointer IS ACCESS CONSTANT Integer;

The first declares a familiar access type, which we now call pool-specific. It can designate only an Integer value allocated from the pool. The second declares a general access type that can designate an integer variable, integer constant, or pool value. The third is a restricted "read-only" form of the second: If P is of this type, it can be dereferenced only to read the designated value, not to write it. That is, P.ALL is not valid on the left side of an assignment statement. This is analogous to an IN parameter.

Given a general access type of the second kind, can its values point to any integer variable or constant? No. In keeping with Ada's general philosophy of explicitness in operations, Ada requires that the programmer indicate explicitly that a variable or constant is intended to be "pointed to." For example, the integer variable X, declared as

    X :Integer;
cannot be designated by an access value, but the variable Y, declared as
    Y: ALIASED Integer;
can indeed be so designated. In everyday English, an alias is a nickname, or a name a person uses in addition to his or her given name. (A criminal might use a number of aliases to avoid detection.) In programming, the term aliased is a fairly standard one, and means, by analogy, that the variable can be referred to not only by its name but by any number of aliases (access values).

Suppose P is a general access type as above. How does P acquire a value? Of course, P can still be copied from another access variable or assigned the result of a NEW, but we are interested in designating variables. We can cause P to designate Y, for example, by writing

    P := Y'Access;
The 'Access attribute returns an access value designating Y, or, informally, a pointer to Y.

Program 15.8 illustrates general access types. An array, PromptTable, is made to contain access values that designate strings of different lengths. The four prompts are declared as ALIASED to allow them to be designated. If we wished the prompts to be CONSTANT strings, the access type would then be written

    TYPE StringPointer IS ACCESS CONSTANT String;

Program 15.8
Illustration of General Access Types

WITH Ada.Text_IO;
PROCEDURE General_Access_Types IS
------------------------------------------------------------------------
--| Illustrates general access types
--| Author: Michael B. Feldman, The George Washington University 
--| Last Modified: September 1995                                     
------------------------------------------------------------------------

  TYPE StringPointer IS ACCESS ALL String;
  -- ALL makes StringPointer a "general access type" as opposed to
  -- a "pool-specific access type." StringPointer values 
  -- can designate declared variables and constants,
  -- as well as dynamically allocated (NEW) values
  
  Prompt1: ALIASED String := "Enter a command >";
  Prompt2: ALIASED String := "Thank you.";
  Prompt3: ALIASED String := "Invalid; try again.";
  Prompt4: ALIASED String := "Bye now.";
  -- ALIASED means 
  --   "able to be designated by a general access value"

  PromptTable: ARRAY (1..4) OF StringPointer :=
    (Prompt1'Access, Prompt2'Access, 
     Prompt3'Access, Prompt4'Access);
  -- We fill the array with access values: for example,
  -- Prompt1'Access returns an access value designating Prompt1
    
BEGIN -- General_Access_Types
  
  -- display all the prompts in the table 
  FOR Which IN PromptTable'Range LOOP
    Ada.Text_IO.Put(Item => PromptTable(Which).ALL); -- dereference
    Ada.Text_IO.New_Line;
  END LOOP;
  
END General_Access_Types;
Sample Run
Enter a command >
Thank you.
Invalid; try again.
Bye now.

Armed with this introduction to general access types, we are ready to use them in a more elaborate discussion of tagged types.


[1] General access types are a new feature of Ada 95; they are not available in Ada 83.


Previous | Next | Table of Contents | Index | Program List | Copyright

Copyright © 1996 by Addison-Wesley Publishing Company, Inc.