5.3 Classwide Types and Dispatching

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

Recall that in Ada terminology the word class (not a reserved word) refers to an entire hierarchy of types derived from a common root type -- a derivation class (tagged or not). When the derivation class is tagged, there is an implicitly declared type known as a classwide type, which comprises the union of all types in the class. (See examples such as "Vehicle'Class" in code below.) A classwide type is an example of an indefinite subtype.

Formal parameters of subprograms associated with tagged types are allowed to belong to a classwide type. When a call is issued to such a subprogram the resulting action is known as a classwide operation and involves an automatic implicit type conversion "toward the root." This is also known as a view conversion because a different view of the object, possibly consisting of fewer components, is generated.

When the formal parameters of subprograms associated with tagged types all have definite types, these become dispatching operations, which may (under certain circumstances) become dynamically dispatched to the appropriate version of the subprogram. Whether or not static dispatching (at compile time) or dynamic dispatching (at run-time) occurs depends on how the client code is written. (See examples in following pages.) In either case it is the "tag" associated with the actual parameters that determines which version is called.

Example Derivation Class of Tagged Types

This subsystem of packages implements the hierarchy modeled in a previous page. It includes the top-level package (Vehicles), two public children, and four public grandchildren. Each package declares one tagged type in the derivation class. Only the package declarations are given here. The seven package bodies are given in the next section.

Im5-4.gif (4778 bytes)

The above diagram represents two hierarchies arranged together. One is a module hierarchy of Ada library packages descended from a common ancestor module (Vehicles). The other is a hierarchy of types descended from a common root type (Vehicle).

Source Code Listing

---------------------------------------------------------------------
--  These package declarations define a hierarchy of military 
--  vehicle types.
---------------------------------------------------------------------
package Vehicles is
  type Str_2 is array(1..2) of Character;  
  type Lat_Type is range -90..90;           
  type Lon_Type is range -180..180;
  type Hdg_Type is mod 360;  
  type Vehicle is abstract tagged private;          -- root type
  
  procedure Rename_Reset(V   : in out Vehicle'Class;-- classwide op
                         Nm  : in Str_2;
                         Lat : in Lat_Type;
                         Lon : in Lon_Type;
                         Hdg : in Hdg_Type);
  procedure Report_Position(V : in Vehicle'Class);  -- classwide op
  
  procedure Change_Heading (V : in out Vehicle;     -- dispatching op
                   H : in Hdg_Type) is abstract;
  procedure Deploy_Weapon (V  : in Vehicle)
                                   is abstract;     -- dispatching op
private  
  type Vehicle is  abstract tagged
    record
      Name      : String(1..2) := "A1";
      Latitude  : Lat_Type := 0;
      Longitude : Lon_Type := 0;
      Heading   : Hdg_Type := 0;
    end record;
end Vehicles;
---------------------------------------------------------------------
package Vehicles.Airplanes is
  type Alt_Type is new Integer range 0..100000;
  type Airplane is abstract new Vehicle with private;  -- extension

  procedure Change_Altitude(A   : in out Aircraft'Class;  -- new op
                            Alt : in Alt_Type);
  procedure Change_Heading(A : in out Aircraft;  -- override operation
                           H : in Hdg_Type);
private
  type Airplane is abstract new Vehicle with
    record
      Altitude : Alt_Type;                       -- new component
    end record;  
end Vehicles.Airplanes;
---------------------------------------------------------------------
package Vehicles.Ships is
  type Ship is abstract new Vehicle with private;-- extension

  procedure Change_Heading(S : in out Ship;      -- override operation
                           H : in Hdg_Type); 
private
  type Ship is abstract new Vehicle with
    null record;                                 -- no new components
end Vehicles.Ships;
---------------------------------------------------------------------
package Vehicles.Airplanes.Fighters is
  type Fighter is new Airplane with private;     -- extension
  procedure Deploy_Weapon (F  : in Fighter);     -- override operation
private
  type Fighter is new Aircraft with
    null record;                                 -- no new components
end Vehicles.Airplanes.Fighters;
---------------------------------------------------------------------
package Vehicles.Airplanes.Bombers is
  type Bomber is new Airplane with private;      -- extension
  procedure Deploy_Weapon (B  : in Bomber);      -- override operation
private
  type Bomber is new Aircraft with
    null record;                                 -- no new components
end Vehicles.Airplanes.Bombers;
---------------------------------------------------------------------
package Vehicles.Ships.Cruisers is
  type Cruiser is new Ship with private;         -- extension
  procedure Deploy_Weapon (C  : in Cruiser);     -- override operation
private
  type Cruiser is new Ship with 
    null record;                                 -- no new components
end Class_Vehicle.Class_Ship.Class_Cruiser;
---------------------------------------------------------------------
package Vehicles.Ships.Submarines is
  type Depth_Type is new Integer range 0..1000;
  type Submarine is new Ship with private;       -- extension
  
  procedure Change_Depth (Sub : in out Submarine;--new operation
                            D : in Depth_Type);
  procedure Deploy_Weapon(Sub : in Submarine);   -- override operation
private
  type Submarine is new Ship with
    record
      Depth : Depth_Type;                        -- new component
    end record;
end Vehicles.Ships.Submarines;
---------------------------------------------------------------------

In each of the dispatching operations declared in the above code, there is one controlling parameter. This is the parameter that determines which version of the overloaded operation will be called. In this case it is the V parameter in the Change_Heading and Deploy_Weapon procedures.

Related Topics

4.12 Derived Types

[ Back to top of pagePrev ] Next ]