- Tagged types and type extensions support object-oriented programming,
based on inheritance with extension and run-time polymorphism via dispatching
- A record type or private type that has the reserved word tagged in its declaration
is called a tagged type. When deriving from a tagged type, additional components
may be defined. As for any derived type, additional primitive subprograms
may be defined, and inherited primitive subprograms may be overridden. The
derived type is called an extension of the ancestor type, or simply a type
extension. Every type extension is also a tagged type, and is either a record
extension or a private extension of some other tagged type. A record extension
is defined by a derived_type_definition with a record_extension_part. A private
extension, which is a partial view of a record extension, can be declared
in the visible part of a package (see 7.3) or in a
generic formal part (see 12.5.1).
- An object of a tagged type has an associated (run-time) tag that identifies
the specific tagged type used to create the object originally. The tag of
an operand of a class-wide tagged type T'Class controls which subprogram body
is to be executed when a primitive subprogram of type T is applied to the
operand (see 3.9.2); using a tag to control which
body to execute is called dispatching.
- The tag of a specific tagged type identifies the full_type_declaration of
the type. If a declaration for a tagged type occurs within a generic_package_declaration, then the corresponding type declarations in distinct
instances of the generic package are associated with distinct tags. For a
tagged type that is local to a generic package body, the language does not
specify whether repeated instantiations of the generic body result in
- The following language-defined library package exists:
package Ada.Tags is
type Tag is private;
function Expanded_Name(T : Tag) return String;
function External_Tag(T : Tag) return String;
function Internal_Tag(External : String) return Tag;
Tag_Error : exception;
... -- not specified by the language
- The function Expanded_Name returns the full expanded name of the first
subtype of the specific type identified by the tag, in upper case, starting
with a root library unit. The result is implementation defined if the type
is declared within an unnamed block_statement.
- The function External_Tag returns a string to be used in an external representation
for the given tag. The call External_Tag(S'Tag) is equivalent to the attribute_reference
S'External_Tag (see 13.3).
- The function Internal_Tag returns the tag that corresponds to the given
external tag, or raises Tag_Error if the given string is not the external tag
for any specific type of the partition.
- For every subtype S of a tagged type T (specific or class-wide), the
following attributes are defined:
S'Class denotes a subtype of the class-wide type (called
T'Class in this International Standard) for the class rooted
at T (or if S already denotes a class-wide subtype, then
S'Class is the same as S).
S'Class is unconstrained. However, if S is constrained,
then the values of S'Class are only those that when converted
to the type T belong to S.
S'Tag denotes the tag of the type T (or if T is class-wide,
the tag of the root type of the corresponding class). The
value of this attribute is of type Tag.
- Given a prefix X that is of a class-wide tagged type (after any implicit
dereference), the following attribute is defined:
X'Tag denotes the tag of X. The value of this attribute is of
- The tag associated with an object of a tagged type is determined as
- The tag of a stand-alone object, a component, or an aggregate of
a specific tagged type T identifies T.
- The tag of an object created by an allocator for an access type
with a specific designated tagged type T, identifies T.
- The tag of an object of a class-wide tagged type is that of its
- The tag of the result returned by a function whose result type is
a specific tagged type T identifies T.
- The tag of the result returned by a function with a class-wide
result type is that of the return expression.
- The tag is preserved by type conversion and by parameter passing. The tag
of a value is the tag of the associated object (see 6.2).
- The implementation of the functions in Ada.Tags may raise Tag_Error if
no specific type corresponding to the tag passed as a parameter exists in the
partition at the time the function is called.
(62) A type declared with the reserved word tagged should normally be
declared in a package_specification, so that new primitive subprograms
can be declared for it.
(63) Once an object has been created, its tag never changes.
(64) Class-wide types are defined to have unknown discriminants (see
3.7). This means that objects of a class-wide type have to be explicitly
initialized (whether created by an object_declaration or an allocator),
and that aggregates have to be explicitly qualified with a specific type
when their expected type is class-wide.
(65) If S denotes an untagged private type whose full type is tagged, then
S'Class is also allowed before the full type definition, but only in the
private part of the package in which the type is declared (see
7.3.1). Similarly, the Class attribute is defined for incomplete types
whose full type is tagged, but only within the library unit in which the
incomplete type is declared (see 3.10.1).
- Examples of tagged record types:
type Point is tagged
X, Y : Real := 0.0;
type Expression is tagged null record;
-- Components will be added by each extension
- Type Extensions
- Dispatching Operations of Tagged Types
- Abstract Types and Subprograms
-- Email comments, additions, corrections, gripes, kudos, etc. to:
Magnus Kempe -- Magnus.Kempe@di.epfl.ch
Page last generated: 95-03-12