Contents Index Search Previous Next
3.9 Tagged Types and Type Extensions
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
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
of the ancestor type, or simply a type extension
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
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
applied to the operand (see 3.9.2
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 distinct
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;
... -- 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).
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 type Tag.
The tag associated
with an object of a tagged type is determined as follows:
- 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 initialization expression.
- 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).
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
Contents Index Search Previous Next Legal