Go to the first, previous, next, last section, table of contents.
-
Tagged types and type extensions support object-oriented programming,
based on inheritance with extension and run-time polymorphism via
dispatching operations.
Static Semantics
-
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 section 7.3 Private Types and Private Extensions, or in a generic
formal part, See section 12.5.1 Formal Private and Derived Types.
-
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 section 3.9.2 Dispatching Operations of Tagged Types, 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 distinct tags.
-
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;
-
private
... -- not specified by the language
end Ada.Tags;
-
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 section 13.3 Representation Attributes.
-
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
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
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
X'Tag denotes the tag of X. The value of this attribute is of
type Tag.
Dynamic Semantics
-
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 section 6.2 Formal Parameter Modes.
Implementation Permissions
-
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.
NOTES
-
(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 section 3.7 Discriminants. 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 section 7.3.1 Private Operations. 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 section 3.10.1 Incomplete Type Declarations.
Examples
-
Examples of tagged record types:
-
type Point is tagged
record
X, Y : Real := 0.0;
end record;
-
type Expression is tagged null record;
-- Components will be added by each extension
- 3.9.1: Type Extensions
- 3.9.2: Dispatching Operations of Tagged Types
- 3.9.3: Abstract Types and Subprograms
Go to the first, previous, next, last section, table of contents.