1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240
|
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<HTML>
<HEAD>
<TITLE>Ada95 - Tagged Types and Type Extensions</TITLE>
<META NAME="Author" CONTENT="JTC1/SC22/WG9/ARG, by Randall Brukardt, ARG Editor">
<META NAME="GENERATOR" CONTENT="Arm_Form.Exe, Ada Reference Manual generator">
<STYLE type="text/css">
DIV.paranum {position: absolute; font-family: Arial, Helvetica, sans-serif; left: 0.5 em; top: auto}
TT {font-family: "Courier New", monospace}
DT {display: compact}
DIV.Normal {font-family: "Times New Roman", Times, serif; margin-bottom: 0.6em}
DIV.Wide {font-family: "Times New Roman", Times, serif; margin-top: 0.6em; margin-bottom: 0.6em}
DIV.Annotations {font-family: "Times New Roman", Times, serif; margin-left: 4.0em; margin-bottom: 0.6em}
DIV.WideAnnotations {font-family: "Times New Roman", Times, serif; margin-left: 4.0em; margin-top: 0.6em; margin-bottom: 0.6em}
DIV.Index {font-family: "Times New Roman", Times, serif}
DIV.SyntaxSummary {font-family: "Times New Roman", Times, serif; margin-left: 2.0em; margin-bottom: 0.4em}
DIV.Notes {font-family: "Times New Roman", Times, serif; margin-left: 2.0em; margin-bottom: 0.6em}
DIV.NotesHeader {font-family: "Times New Roman", Times, serif; margin-left: 2.0em}
DIV.SyntaxIndented {font-family: "Times New Roman", Times, serif; margin-left: 2.0em; margin-bottom: 0.4em}
DIV.Indented {font-family: "Times New Roman", Times, serif; margin-left: 6.0em; margin-bottom: 0.6em}
DIV.CodeIndented {font-family: "Times New Roman", Times, serif; margin-left: 4.0em; margin-bottom: 0.6em}
DIV.SmallIndented {font-family: "Times New Roman", Times, serif; margin-left: 10.0em; margin-bottom: 0.6em}
DIV.SmallCodeIndented {font-family: "Times New Roman", Times, serif; margin-left: 8.0em; margin-bottom: 0.6em}
DIV.Examples {font-family: "Courier New", monospace; margin-left: 2.0em; margin-bottom: 0.6em}
DIV.SmallExamples {font-family: "Courier New", monospace; font-size: 80%; margin-left: 7.5em; margin-bottom: 0.6em}
DIV.IndentedExamples {font-family: "Courier New", monospace; margin-left: 8.0em; margin-bottom: 0.6em}
DIV.SmallIndentedExamples {font-family: "Courier New", monospace; font-size: 80%; margin-left: 15.0em; margin-bottom: 0.6em}
UL.Bulleted {font-family: "Times New Roman", Times, serif; margin-left: 2.0em; margin-right: 2.0em; margin-top: 0em; margin-bottom: 0.5em}
UL.SmallBulleted {font-family: "Times New Roman", Times, serif; margin-left: 6.0em; margin-right: 6.0em; margin-top: 0em; margin-bottom: 0.5em}
UL.NestedBulleted {font-family: "Times New Roman", Times, serif; margin-left: 4.0em; margin-right: 4.0em; margin-top: 0em; margin-bottom: 0.5em}
UL.SmallNestedBulleted {font-family: "Times New Roman", Times, serif; margin-left: 8.0em; margin-right: 8.0em; margin-top: 0em; margin-bottom: 0.5em}
UL.IndentedBulleted {font-family: "Times New Roman", Times, serif; margin-left: 8.0em; margin-right: 8.0em; margin-top: 0em; margin-bottom: 0.5em}
UL.CodeIndentedBulleted {font-family: "Times New Roman", Times, serif; margin-left: 6.0em; margin-right: 6.0em; margin-top: 0em; margin-bottom: 0.5em}
UL.CodeIndentedNestedBulleted {font-family: "Times New Roman", Times, serif; margin-left: 8.0em; margin-right: 8.0em; margin-top: 0em; margin-bottom: 0.5em}
UL.SyntaxIndentedBulleted {font-family: "Times New Roman", Times, serif; margin-left: 4.0em; margin-right: 4.0em; margin-top: 0em; margin-bottom: 0.5em}
UL.NotesBulleted {font-family: "Times New Roman", Times, serif; margin-left: 4.0em; margin-right: 4.0em; margin-top: 0em; margin-bottom: 0.5em}
UL.NotesNestedBulleted {font-family: "Times New Roman", Times, serif; margin-left: 6.0em; margin-right: 6.0em; margin-top: 0em; margin-bottom: 0.5em}
DL.Hanging {font-family: "Times New Roman", Times, serif; margin-top: 0em; margin-bottom: 0.6em}
DD.Hanging {margin-left: 6.0em}
DL.IndentedHanging {font-family: "Times New Roman", Times, serif; margin-left: 4.0em; margin-top: 0em; margin-bottom: 0.6em}
DD.IndentedHanging {margin-left: 2.0em}
DL.HangingInBulleted {font-family: "Times New Roman", Times, serif; margin-left: 2.0em; margin-right: 2.0em; margin-top: 0em; margin-bottom: 0.5em}
DD.HangingInBulleted {margin-left: 4.0em}
DL.SmallHanging {font-family: "Times New Roman", Times, serif; margin-left: 4.0em; margin-top: 0em; margin-bottom: 0.6em}
DD.SmallHanging {margin-left: 7.5em}
DL.SmallIndentedHanging {font-family: "Times New Roman", Times, serif; margin-left: 8.0em; margin-top: 0em; margin-bottom: 0.6em}
DD.SmallIndentedHanging {margin-left: 2.0em}
DL.SmallHangingInBulleted {font-family: "Times New Roman", Times, serif; margin-left: 6.0em; margin-right: 6.0em; margin-top: 0em; margin-bottom: 0.5em}
DD.SmallHangingInBulleted {margin-left: 5.0em}
DL.Enumerated {font-family: "Times New Roman", Times, serif; margin-right: 0.0em; margin-top: 0em; margin-bottom: 0.5em}
DD.Enumerated {margin-left: 2.0em}
DL.SmallEnumerated {font-family: "Times New Roman", Times, serif; margin-left: 4.0em; margin-right: 4.0em; margin-top: 0em; margin-bottom: 0.5em}
DD.SmallEnumerated {margin-left: 2.5em}
DL.NestedEnumerated {font-family: "Times New Roman", Times, serif; margin-left: 2.0em; margin-right: 2.0em; margin-top: 0em; margin-bottom: 0.5em}
DL.SmallNestedEnumerated {font-family: "Times New Roman", Times, serif; margin-left: 6.0em; margin-right: 6.0em; margin-top: 0em; margin-bottom: 0.5em}
</STYLE>
</HEAD>
<BODY TEXT="#000000" BGCOLOR="#FFFFF0" LINK="#0000FF" VLINK="#800080" ALINK="#FF0000">
<P><A HREF="RM-TOC.html">Contents</A> <A HREF="RM-0-29.html">Index</A> <A HREF="RM-3-8-1.html">Previous</A> <A HREF="RM-3-9-1.html">Next</A></P>
<HR>
<H1> 3.9 Tagged Types and Type Extensions</H1>
<DIV Class="Paranum"><FONT SIZE=-2>1</FONT></DIV>
<DIV Class="Normal"> <A NAME="I1941"></A><A NAME="I1942"></A><A NAME="I1943"></A><A NAME="I1944"></A><A NAME="I1945"></A>Tagged
types and type extensions support object-oriented programming, based
on inheritance with extension and run-time polymorphism via <I>dispatching
operations</I>. <A NAME="I1946"></A><A NAME="I1947"></A><A NAME="I1948"></A></DIV>
<H4 ALIGN=CENTER>Static Semantics</H4>
<DIV Class="Paranum"><FONT SIZE=-2>2</FONT></DIV>
<DIV Class="Normal"> <A NAME="I1949"></A>A record type or private type
that has the reserved word <B>tagged</B> in its declaration is called
a <I>tagged</I> 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.
<A NAME="I1950"></A><A NAME="I1951"></A>The derived type is called an
<I>extension</I> of the ancestor type, or simply a <I>type extension</I>.
<A NAME="I1952"></A><A NAME="I1953"></A><A NAME="I1954"></A>Every type
extension is also a tagged type, and is either a <I>record extension</I>
or a <I>private extension</I> of some other tagged type. A record extension
is defined by a <FONT FACE="Arial, Helvetica">derived_type_definition</FONT>
with a <FONT FACE="Arial, Helvetica">record_extension_part</FONT>. A
private extension, which is a partial view of a record extension, can
be declared in the visible part of a package (see <A HREF="RM-7-3.html">7.3</A>)
or in a generic formal part (see <A HREF="RM-12-5-1.html">12.5.1</A>).
</DIV>
<DIV Class="Paranum"><FONT SIZE=-2>3</FONT></DIV>
<DIV Class="Normal"> <A NAME="I1955"></A>An object of a tagged type
has an associated (run-time) <I>tag</I> that identifies the specific
tagged type used to create the object originally. The tag of an operand
of a class-wide tagged type <I>T</I>'Class controls which subprogram
body is to be executed when a primitive subprogram of type <I>T</I> is
applied to the operand (see <A HREF="RM-3-9-2.html">3.9.2</A>); <A NAME="I1956"></A>using
a tag to control which body to execute is called <I>dispatching</I>.
<A NAME="I1957"></A><A NAME="I1958"></A><A NAME="I1959"></A><A NAME="I1960"></A></DIV>
<DIV Class="Paranum"><FONT SIZE=-2>4</FONT></DIV>
<DIV Class="Normal"> The tag of a specific tagged type identifies the
<FONT FACE="Arial, Helvetica">full_type_declaration</FONT> of the type.
If a declaration for a tagged type occurs within a <FONT FACE="Arial, Helvetica">generic_package_declaration</FONT>,
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. </DIV>
<DIV Class="Paranum"><FONT SIZE=-2>5</FONT></DIV>
<DIV Class="Normal" Style="margin-bottom: 0.4em"> The following language-defined
library package exists: </DIV>
<DIV Class="Paranum"><FONT SIZE=-2>6</FONT></DIV>
<DIV Class="Examples"><TT><A NAME="I1961"></A><A NAME="I1962"></A><A NAME="I1963"></A><B>package</B> Ada.Tags <B>is</B><BR>
<B>type</B> <A NAME="I1964"></A><A NAME="I1965"></A>Tag <B>is</B> <B>private</B>;</TT></DIV>
<DIV Class="Paranum"><FONT SIZE=-2>7</FONT></DIV>
<DIV Class="Examples"><TT> <B>function</B> <A NAME="I1966"></A><A NAME="I1967"></A>Expanded_Name(T : Tag) <B>return</B> String;<BR>
<B>function</B> <A NAME="I1968"></A><A NAME="I1969"></A>External_Tag(T : Tag) <B>return</B> String;<BR>
<B>function</B> <A NAME="I1970"></A><A NAME="I1971"></A>Internal_Tag(External : String) <B>return</B> Tag;</TT></DIV>
<DIV Class="Paranum"><FONT SIZE=-2>8</FONT></DIV>
<DIV Class="Examples"><TT> <A NAME="I1972"></A>Tag_Error : <B>exception</B>;</TT></DIV>
<DIV Class="Paranum"><FONT SIZE=-2>9</FONT></DIV>
<DIV Class="Examples"><TT><B>private</B><BR>
... -- <I>not specified by the language</I><BR>
<B>end</B> Ada.Tags;</TT></DIV>
<DIV Class="Paranum"><FONT SIZE=-2>10</FONT></DIV>
<DIV Class="Normal"> 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 <FONT FACE="Arial, Helvetica">block_statement</FONT>.
</DIV>
<DIV Class="Paranum"><FONT SIZE=-2>11</FONT></DIV>
<DIV Class="Normal"> 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 <FONT FACE="Arial, Helvetica">attribute_reference</FONT>
S'External_Tag (see <A HREF="RM-13-3.html">13.3</A>). </DIV>
<DIV Class="Paranum"><FONT SIZE=-2>12</FONT></DIV>
<DIV Class="Normal"> 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.</DIV>
<DIV Class="Paranum"><FONT SIZE=-2>13</FONT></DIV>
<DIV Class="Normal"> For every subtype S of a tagged type <I>T</I>
(specific or class-wide), the following attributes are defined: </DIV>
<DIV Class="Paranum"><FONT SIZE=-2>14</FONT></DIV>
<DL Class="Hanging"><DT> S'Class<DD Class="Hanging">
<A NAME="I1973"></A><A NAME="I1974"></A>S'Class denotes a subtype of
the class-wide type (called <I>T</I>'Class in this International Standard)
for the class rooted at <I>T</I> (or if S already denotes a class-wide
subtype, then S'Class is the same as S).</DL>
<DIV Class="Paranum"><FONT SIZE=-2>15</FONT></DIV>
<DL Class="Hanging"><DD Class ="Hanging"><A NAME="I1975"></A><A NAME="I1976"></A>S'Class
is unconstrained. However, if S is constrained, then the values of S'Class
are only those that when converted to the type <I>T</I> belong to S.
</DL>
<DIV Class="Paranum"><FONT SIZE=-2>16</FONT></DIV>
<DL Class="Hanging"><DT> S'Tag<DD Class="Hanging">
<A NAME="I1977"></A><A NAME="I1978"></A>S'Tag denotes the tag of the
type <I>T</I> (or if <I>T</I> is class-wide, the tag of the root type
of the corresponding class). The value of this attribute is of type Tag.
</DL>
<DIV Class="Paranum"><FONT SIZE=-2>17</FONT></DIV>
<DIV Class="Normal"> Given a <FONT FACE="Arial, Helvetica">prefix</FONT>
X that is of a class-wide tagged type (after any implicit dereference),
the following attribute is defined: </DIV>
<DIV Class="Paranum"><FONT SIZE=-2>18</FONT></DIV>
<DL Class="Hanging"><DT> X'Tag<DD Class="Hanging">
<A NAME="I1979"></A><A NAME="I1980"></A>X'Tag denotes the tag of X. The
value of this attribute is of type Tag. </DL>
<H4 ALIGN=CENTER>Dynamic Semantics</H4>
<DIV Class="Paranum"><FONT SIZE=-2>19</FONT></DIV>
<DIV Class="Normal" Style="margin-bottom: 0.4em"> The tag associated
with an object of a tagged type is determined as follows: </DIV>
<DIV Class="Paranum"><FONT SIZE=-2>20</FONT></DIV>
<UL Class="Bulleted"><LI TYPE=DISC><A NAME="I1981"></A>The tag of a stand-alone object, a
component, or an <FONT FACE="Arial, Helvetica">aggregate</FONT> of a
specific tagged type <I>T</I> identifies <I>T</I>. </LI></UL>
<DIV Class="Paranum"><FONT SIZE=-2>21</FONT></DIV>
<UL Class="Bulleted"><LI TYPE=DISC><A NAME="I1982"></A>The tag of an object created by an
allocator for an access type with a specific designated tagged type <I>T</I>,
identifies <I>T</I>. </LI></UL>
<DIV Class="Paranum"><FONT SIZE=-2>22</FONT></DIV>
<UL Class="Bulleted"><LI TYPE=DISC><A NAME="I1983"></A>The tag of an object of a class-wide
tagged type is that of its initialization expression. </LI></UL>
<DIV Class="Paranum"><FONT SIZE=-2>23</FONT></DIV>
<UL Class="Bulleted"><LI TYPE=DISC><A NAME="I1984"></A>The tag of the result returned by a
function whose result type is a specific tagged type <I>T</I> identifies
<I>T</I>. </LI></UL>
<DIV Class="Paranum"><FONT SIZE=-2>24</FONT></DIV>
<UL Class="Bulleted"><LI TYPE=DISC><A NAME="I1985"></A>The tag of the result returned by a
function with a class-wide result type is that of the return expression.
</LI></UL>
<DIV Class="Paranum"><FONT SIZE=-2>25</FONT></DIV>
<DIV Class="Normal"> <A NAME="I1986"></A>The tag is preserved by type
conversion and by parameter passing. The tag of a value is the tag of
the associated object (see <A HREF="RM-6-2.html">6.2</A>).</DIV>
<H4 ALIGN=CENTER>Implementation Permissions</H4>
<DIV Class="Paranum"><FONT SIZE=-2>26</FONT></DIV>
<DIV Class="Normal"> 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.
</DIV>
<DIV Class="NotesHeader"><FONT SIZE=-1>NOTES</FONT></DIV>
<DIV Class="Paranum"><FONT SIZE=-2>27</FONT></DIV>
<DIV Class="Notes"><FONT SIZE=-1>62 A type declared with the
reserved word <B>tagged</B> should normally be declared in a <FONT FACE="Arial, Helvetica">package_specification</FONT>,
so that new primitive subprograms can be declared for it.</FONT></DIV>
<DIV Class="Paranum"><FONT SIZE=-2>28</FONT></DIV>
<DIV Class="Notes"><FONT SIZE=-1>63 Once an object has been
created, its tag never changes.</FONT></DIV>
<DIV Class="Paranum"><FONT SIZE=-2>29</FONT></DIV>
<DIV Class="Notes"><FONT SIZE=-1>64 Class-wide types are defined
to have unknown discriminants (see <A HREF="RM-3-7.html">3.7</A>). This
means that objects of a class-wide type have to be explicitly initialized
(whether created by an <FONT FACE="Arial, Helvetica">object_declaration</FONT>
or an <FONT FACE="Arial, Helvetica">allocator</FONT>), and that <FONT FACE="Arial, Helvetica">aggregate</FONT>s
have to be explicitly qualified with a specific type when their expected
type is class-wide.</FONT></DIV>
<DIV Class="Paranum"><FONT SIZE=-2>30</FONT></DIV>
<DIV Class="Notes"><FONT SIZE=-1>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 <A HREF="RM-7-3-1.html">7.3.1</A>).
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 <A HREF="RM-3-10-1.html">3.10.1</A>).</FONT></DIV>
<H4 ALIGN=CENTER>Examples</H4>
<DIV Class="Paranum"><FONT SIZE=-2>31</FONT></DIV>
<DIV Class="Normal" Style="margin-bottom: 0.4em"> <I>Examples of
tagged record types:</I> </DIV>
<DIV Class="Paranum"><FONT SIZE=-2>32</FONT></DIV>
<DIV Class="Examples"><TT><B>type</B> Point <B>is tagged</B><BR>
<B>record</B><BR>
X, Y : Real := 0.0;<BR>
<B>end record</B>;</TT></DIV>
<DIV Class="Paranum"><FONT SIZE=-2>33</FONT></DIV>
<DIV Class="Examples"><TT><B>type</B> Expression <B>is tagged null record</B>;<BR>
<I>-- Components will be added by each extension</I></TT></DIV>
<HR>
<P><A HREF="RM-TOC.html">Contents</A> <A HREF="RM-0-29.html">Index</A> <A HREF="RM-3-8-1.html">Previous</A> <A HREF="RM-3-9-1.html">Next</A> <A HREF="RM-TTL.html">Legal</A></P>
</BODY>
</HTML>
|