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
|
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta name="generator" content=
"HTML Tidy for Cygwin (vers 1st April 2002), see www.w3.org">
<meta http-equiv="Content-Type" content=
"text/html; charset=windows-1252">
<meta name="GENERATOR" content="Microsoft FrontPage 4.0">
<meta name="ProgId" content="FrontPage.Editor.Document">
<title>Header boost/cast.hpp Documentation</title>
</head>
<body bgcolor="#FFFFFF" text="#000000">
<h1><img src="../../boost.png" alt="boost.png (6897 bytes)" align=
"middle" width="277" height="86">Header <a href=
"../../boost/cast.hpp">boost/cast.hpp</a></h1>
<h2><a name="Cast Functions">Cast Functions</a></h2>
<p>The header <a href="../../boost/cast.hpp">boost/cast.hpp</a> provides
<a href="#Polymorphic_cast"><b>polymorphic_cast</b></a>, <a href=
"#Polymorphic_cast"><b>polymorphic_downcast</b></a>, and <a href=
"#numeric_cast"><b>numeric_cast</b></a> function templates designed to
complement the C++ built-in casts.</p>
<p>The program <a href="cast_test.cpp">cast_test.cpp</a> can be used to
verify these function templates work as expected.</p>
<h3><a name="Polymorphic_cast">Polymorphic casts</a></h3>
<p>Pointers to polymorphic objects (objects of classes which define at
least one virtual function) are sometimes downcast or crosscast.
Downcasting means casting from a base class to a derived class.
Crosscasting means casting across an inheritance hierarchy diagram, such
as from one base to the other in a <b>Y</b> diagram hierarchy.</p>
<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
safety, suffer poor readability, and are difficult to locate with search
tools.</p>
<p>The C++ built-in <b>static_cast</b> can be used for efficiently
downcasting pointers to polymorphic objects, but provides no error
detection for the case where the pointer being cast actually points to
the wrong derived class. The <b>polymorphic_downcast</b> template retains
the efficiency of <b>static_cast</b> for non-debug compilations, but for
debug compilations adds safety via an assert() that a <b>dynamic_cast</b>
succeeds.</p>
<p>The C++ built-in <b>dynamic_cast</b> can be used for downcasts and
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,
easy to forget to test. The throwing form of <b>dynamic_cast</b>, which
works on references, can be used on pointers through the ugly expression
&<code>dynamic_cast<T&>(*p)</code>, which causes undefined
behavior if <code>p</code> is <code>0</code>. The <b>polymorphic_cast</b>
template performs a <b>dynamic_cast</b> on a pointer, and throws an
exception if the <b>dynamic_cast</b> returns 0.</p>
<p>A <b>polymorphic_downcast</b> is preferred when debug-mode tests will
cover 100% of the object types possibly cast and when non-debug-mode
efficiency is an issue. If these two conditions are not present,
<b>polymorphic_cast</b> is preferred. It must also be used for
crosscasts. It does an assert( dynamic_cast<Derived>(x) == x )
where x is the base pointer, ensuring that not only is a non-zero pointer
returned, but also that it correct in the presence of multiple
inheritance. <b>Warning:</b>: Because <b>polymorphic_downcast</b> uses
assert(), it violates the one definition rule (ODR) if NDEBUG is
inconsistently defined across translation units. [See ISO Std 3.2]</p>
<p>The C++ built-in <b>dynamic_cast</b> must be used to cast references
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
an error condition.</p>
<h3>polymorphic_cast and polymorphic_downcast synopsis</h3>
<blockquote>
<pre>
namespace boost {
template <class Derived, class Base>
inline Derived polymorphic_cast(Base* x);
// Throws: std::bad_cast if ( dynamic_cast<Derived>(x) == 0 )
// Returns: dynamic_cast<Derived>(x)
template <class Derived, class Base>
inline Derived polymorphic_downcast(Base* x);
// Effects: assert( dynamic_cast<Derived>(x) == x );
// Returns: static_cast<Derived>(x)
}
</pre>
</blockquote>
<h3>polymorphic_downcast example</h3>
<blockquote>
<pre>
#include <boost/cast.hpp>
...
class Fruit { public: virtual ~Fruit(){}; ... };
class Banana : public Fruit { ... };
...
void f( Fruit * fruit ) {
// ... logic which leads us to believe it is a Banana
Banana * banana = boost::polymorphic_downcast<Banana*>(fruit);
...
</pre>
</blockquote>
<h3><a name="numeric_cast">numeric_cast</a></h3>
<p>A <b>static_cast</b> or implicit conversion will not detect failure to
preserve range for numeric casts. The <b>numeric_cast</b> function
templates are similar to <b>static_cast</b> and certain (dubious)
implicit conversions in this respect, except that they detect loss of
numeric range. An exception is thrown when a runtime value-preservation
check fails.</p>
<p>The requirements on the argument and result types are:</p>
<blockquote>
<ul>
<li>Both argument and result types are CopyConstructible [ISO Std
20.1.3].</li>
<li>Both argument and result types are Numeric, defined by
<code>std::numeric_limits<>::is_specialized</code> being
true.</li>
<li>The argument can be converted to the result type using
<b>static_cast</b>.</li>
</ul>
</blockquote>
<h3>numeric_cast synopsis</h3>
<blockquote>
<pre>
namespace boost {
class bad_numeric_cast : public std::bad_cast {...};
template<typename Target, typename Source>
inline Target numeric_cast(Source arg);
// Throws: bad_numeric_cast unless, in converting arg from Source to Target,
// there is no loss of negative range, and no underflow, and no
// overflow, as determined by std::numeric_limits
// Returns: static_cast<Target>(arg)
}
</pre>
</blockquote>
<h3>numeric_cast example</h3>
<blockquote>
<pre>
#include <boost/cast.hpp>
using namespace boost::cast;
void ariane(double vx)
{
...
unsigned short dx = numeric_cast<unsigned short>(vx);
...
}
</pre>
</blockquote>
<h3>numeric_cast rationale</h3>
<p>The form of the throws condition is specified so that != is not a
required operation.</p>
<h3>History</h3>
<p><b>polymorphic_cast</b> was suggested by Bjarne Stroustrup in "The C++
Programming Language".<br>
<b>polymorphic_downcast</b> was contributed by <a href=
"../../people/dave_abrahams.htm">Dave Abrahams</a>.<b><br>
numeric_cast</b> was contributed by <a href=
"../../people/kevlin_henney.htm">Kevlin Henney</a>.</p>
<hr>
<p>Revised
<!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %B, %Y" startspan
-->06 January, 2001
<!--webbot bot="Timestamp" endspan i-checksum="38320"
--></p>
<p>© Copyright boost.org 1999. Permission to copy, use, modify, sell
and distribute this document is granted provided this copyright notice
appears in all copies. This document is provided "as is" without express
or implied warranty, and with no claim as to its suitability for any
purpose.</p>
</body>
</html>
|