4.9 Private Types

[ Table of Contents ] Prev ] Chapter Overview ] Next ] [ Glossary/Index ]

A private type is given a partial declaration in the visible part of a package declaration by writing

     type My_Type is private; 

and a full declaration in the private part of the same package declaration, following the reserved word private. (Illustrations of private types appeared in the ADT stack and the generic stack examples in Chapter 2.) We say that there are two views of the type, the partial view and the full view.

Every private type is also one of the types discussed elsewhere in this chapter, such as array type, record type, etc. It is made private by the first step of the two-step declaration --always in a package declaration. Clients of the package can declare instances of the type, but cannot access the hidden details of the structure, which are private.

Clients are restricted as to how they can manipulate objects based on private types. For example, they can call certain subprograms declared in the visible part of the package declaration that the type is declared in, if those subprograms have one or more parameters of the private type. They may also use assignment and comparison for equality or inequality if the type is not declared as limited. The example given below contains an ADT package that exports a limited private type called Queue. It is adapted from the case study in Chapter 5 of [Ben-Ari98].

Example Program Illustrating a Limited Private Type

Clients can manipulate objects of type Queue using three operations: one function and two procedures. The private part of the package fully declares Queue as a discriminated record with two components, one of which is an array of natural integers.

Im4-10.gif (5984 bytes)

Note that the Overflow and Underflow exceptions may be raised by raise statements in the Insert and Remove operations, respectively. If raised, they are handled in the Test_Queue main procedure.

Source Code Listing

---------------------  Priority_Queue  ----------------------
--  This package creates an abstract data type called Queue. 
--  Objects of type Queue have three legal operations: Empty, 
--  Insert, and Remove. 
package Priority_Queue is
  type Queue(Size : Positive) is limited private;
  function  Empty (Q : in Queue) return Boolean;
  procedure Insert(I : in  Integer; Q : in out Queue);
  procedure Remove(I : out Integer; Q : in out Queue);
  Overflow, Underflow : exception;
  type Q_Array is array(Natural range <>) of Integer;
  type Queue(Size : Positive) is 
      Data : Q_Array(0..Size);
      Free : Natural := 0;
    end record;     
end Priority_Queue;
package body Priority_Queue is   
  function Empty(Q : in Queue) return Boolean is
    return Q.Free = 0;    
  end Empty;
  procedure Insert(I : in  Integer; Q : in out Queue) is
    Index : Integer range Q.Data'Range := 0;
    if Q.Free = Q.Size then
      raise Overflow;  
    end if;
    Q.Data(Q.Free) := I;            -- find place to insert
    while Q.Data(Index) < I loop
      Index := Index + 1;                                
    end loop;
    if Index < Q.Free then          -- shift items and insert
      Q.Data(Index+1..Q.Free):= Q.Data(Index..Q.Free-1);
      Q.Data(Index) := I;  
    end if;
    Q.Free := Q.Free+1;     
  end Insert;
  procedure Remove(I : out Integer; Q : in out Queue) is
    if Q.Free = 0 then 
      raise Underflow;  
    end if;
    I := Q.Data(0);
    Q.Free := Q.Free-1;
    Q.Data(0..Q.Free-1) := Q.Data(1..Q.Free);  
  end Remove;
end Priority_Queue;
----------------------  Test_Queue  -------------------------
--  This test procedure declares a priority queue called PQ, 
--  then inserts five integers, then removes five integers, 
--  then tries to remove another -- causing the Underflow 
--  exception to be raised. 
with Priority_Queue;
with Ada.Text_IO; use Ada.Text_IO;
with Ada.Integer_Text_IO; use Ada.Integer_Text_IO;
procedure Test_Queue is
  PQ    : Priority_Queue.Queue(100);  
  Item  : Integer;                        -- Queue item
  Test_Data : array(Positive range <>) of Integer
            := (22, 35, 7, -16, 41, 10);
  for N in Test_Data'Range loop           -- insert array
    Put(Test_Data(N), Width => 5);
    Priority_Queue.Insert(Test_Data(N), PQ);
  end loop;
  while not Priority_Queue.Empty(PQ) loop -- remove array
    Priority_Queue.Remove(Item, PQ);
    Put(Item, Width => 5);  
  end loop;
  Priority_Queue.Remove(Item, PQ);        -- test Underflow
  when Priority_Queue.Underflow => Put("Underflow occurred");
  when Priority_Queue.Overflow  => Put("Overflow occurred");
end Test_Queue;

The above program produces the following output:

         22    35     7   -16    41    10
        -16     7    10    22    35    41
     Underflow occurred

Related Topics

2.10 Abstract (ADT) Stack 4.1 Type System Overview

[ Back to top of pagePrev ] Next ]