[SVN r27509]
This commit is contained in:
Dave Abrahams
2005-02-26 14:58:12 +00:00
parent b8c373ab47
commit 462025d8e6

View File

@@ -20,9 +20,9 @@
<h2><a name="Cast Functions">Cast Functions</a></h2> <h2><a name="Cast Functions">Cast Functions</a></h2>
<p>The header <a href="../../boost/cast.hpp">boost/cast.hpp</a> provides <p>The header <a href="../../boost/cast.hpp">boost/cast.hpp</a> provides
<a href="#Polymorphic_cast"><b>polymorphic_cast</b></a>, <a href= <a href="#Polymorphic_cast"><code>polymorphic_cast</code></a>, <a href=
"#Polymorphic_cast"><b>polymorphic_downcast</b></a>, and <a href= "#Polymorphic_cast"><code>polymorphic_downcast</code></a>, and <a href=
"#numeric_cast"><b>numeric_cast</b></a> function templates designed to "#numeric_cast"><code>numeric_cast</code></a> function templates designed to
complement the C++ built-in casts.</p> complement the C++ built-in casts.</p>
<p>The program <a href="cast_test.cpp">cast_test.cpp</a> can be used to <p>The program <a href="cast_test.cpp">cast_test.cpp</a> can be used to
@@ -34,43 +34,51 @@
least one virtual function) are sometimes downcast or crosscast. least one virtual function) are sometimes downcast or crosscast.
Downcasting means casting from a base class to a derived class. Downcasting means casting from a base class to a derived class.
Crosscasting means casting across an inheritance hierarchy diagram, such Crosscasting means casting across an inheritance hierarchy diagram, such
as from one base to the other in a <b>Y</b> diagram hierarchy.</p> as from one base to the other in a <code>Y</code> diagram hierarchy.</p>
<p>Such casts can be done with old-style casts, but this approach is <p>Such casts can be done with old-style casts, but this approach is
never to be recommended. Old-style casts are sorely lacking in type never to be recommended. Old-style casts are sorely lacking in type
safety, suffer poor readability, and are difficult to locate with search safety, suffer poor readability, and are difficult to locate with search
tools.</p> tools.</p>
<p>The C++ built-in <b>static_cast</b> can be used for efficiently <p>The C++ built-in <code>static_cast</code> can be used for efficiently
downcasting pointers to polymorphic objects, but provides no error downcasting pointers to polymorphic objects, but provides no error
detection for the case where the pointer being cast actually points to detection for the case where the pointer being cast actually points to
the wrong derived class. The <b>polymorphic_downcast</b> template retains the wrong derived class. The <code>polymorphic_downcast</code> template retains
the efficiency of <b>static_cast</b> for non-debug compilations, but for the efficiency of <code>static_cast</code> for non-debug compilations, but for
debug compilations adds safety via an assert() that a <b>dynamic_cast</b> debug compilations adds safety via an assert() that a <code>dynamic_cast</code>
succeeds.</p> succeeds.</p>
<p>The C++ built-in <b>dynamic_cast</b> can be used for downcasts and <p>The C++ built-in <code>dynamic_cast</code> can be used for downcasts and
crosscasts of pointers to polymorphic objects, but error notification in crosscasts of pointers to polymorphic objects, but error notification in
the form of a returned value of 0 is inconvenient to test, or worse yet, the form of a returned value of 0 is inconvenient to test, or worse yet,
easy to forget to test. The throwing form of <b>dynamic_cast</b>, which easy to forget to test. The throwing form of <code>dynamic_cast</code>, which
works on references, can be used on pointers through the ugly expression works on references, can be used on pointers through the ugly expression
&amp;<code>dynamic_cast&lt;T&amp;&gt;(*p)</code>, which causes undefined &amp;<code>dynamic_cast&lt;T&amp;&gt;(*p)</code>, which causes undefined
behavior if <code>p</code> is <code>0</code>. The <b>polymorphic_cast</b> behavior if <code>p</code> is <code>0</code>. The <code>polymorphic_cast</code>
template performs a <b>dynamic_cast</b> on a pointer, and throws an template performs a <code>dynamic_cast</code> on a pointer, and throws an
exception if the <b>dynamic_cast</b> returns 0.</p> exception if the <code>dynamic_cast</code> returns 0.</p>
<p>A <b>polymorphic_downcast</b> is preferred when debug-mode tests will <p>A <code>polymorphic_downcast</code> should be used for
cover 100% of the object types possibly cast and when non-debug-mode downcasts that you are certain should succeed. Error checking is
efficiency is an issue. If these two conditions are not present, only performed in translation units where <code>NDEBUG</code> is
<b>polymorphic_cast</b> is preferred. It must also be used for not defined, via
crosscasts. It does an assert( dynamic_cast&lt;Derived&gt;(x) == x ) <pre>
where x is the base pointer, ensuring that not only is a non-zero pointer assert( dynamic_cast&lt;Derived&gt;(x) == x )
returned, but also that it correct in the presence of multiple </pre> where <code>x</code> is the source pointer. This approach
inheritance. <b>Warning:</b>: Because <b>polymorphic_downcast</b> uses ensures that not only is a non-zero pointer returned, but also
assert(), it violates the one definition rule (ODR) if NDEBUG is that it is correct in the presence of multiple inheritance.
inconsistently defined across translation units. [See ISO Std 3.2]</p> Attempts to crosscast using <code>polymorphic_downcast</code> will
fail to compile.
<b>Warning:</b> Because <code>polymorphic_downcast</code> uses assert(), it
violates the One Definition Rule (ODR) if NDEBUG is inconsistently
defined across translation units. [See ISO Std 3.2]
</p><p>
For crosscasts, or when the success of a cast can only be known at
runtime, or when efficiency is not important,
<code>polymorphic_cast</code> is preferred. </p>
<p>The C++ built-in <b>dynamic_cast</b> must be used to cast references <p>The C++ built-in <code>dynamic_cast</code> must be used to cast references
rather than pointers. It is also the only cast that can be used to check rather than pointers. It is also the only cast that can be used to check
whether a given interface is supported; in that case a return of 0 isn't whether a given interface is supported; in that case a return of 0 isn't
an error condition.</p> an error condition.</p>
@@ -113,9 +121,9 @@ void f( Fruit * fruit ) {
<h3><a name="numeric_cast">numeric_cast</a></h3> <h3><a name="numeric_cast">numeric_cast</a></h3>
<p>A <b>static_cast</b> or implicit conversion will not detect failure to <p>A <code>static_cast</code> or implicit conversion will not detect failure to
preserve range for numeric casts. The <b>numeric_cast</b> function preserve range for numeric casts. The <code>numeric_cast</code> function
templates are similar to <b>static_cast</b> and certain (dubious) templates are similar to <code>static_cast</code> and certain (dubious)
implicit conversions in this respect, except that they detect loss of implicit conversions in this respect, except that they detect loss of
numeric range. An exception is thrown when a runtime value-preservation numeric range. An exception is thrown when a runtime value-preservation
check fails.</p> check fails.</p>
@@ -132,7 +140,7 @@ void f( Fruit * fruit ) {
true.</li> true.</li>
<li>The argument can be converted to the result type using <li>The argument can be converted to the result type using
<b>static_cast</b>.</li> <code>static_cast</code>.</li>
</ul> </ul>
</blockquote> </blockquote>
@@ -178,11 +186,11 @@ void ariane(double vx)
<h3>History</h3> <h3>History</h3>
<p><b>polymorphic_cast</b> was suggested by Bjarne Stroustrup in "The C++ <p><code>polymorphic_cast</code> was suggested by Bjarne Stroustrup in "The C++
Programming Language".<br> Programming Language".<br>
<b>polymorphic_downcast</b> was contributed by <a href= <code>polymorphic_downcast</code> was contributed by <a href=
"../../people/dave_abrahams.htm">Dave Abrahams</a>.<b><br> "../../people/dave_abrahams.htm">Dave Abrahams</a>.<code><br>
numeric_cast</b> was contributed by <a href= numeric_cast</code> was contributed by <a href=
"../../people/kevlin_henney.htm">Kevlin Henney</a>.</p> "../../people/kevlin_henney.htm">Kevlin Henney</a>.</p>
<hr> <hr>