[12] | 1 | <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> |
---|
| 2 | |
---|
| 3 | <html> |
---|
| 4 | <head> |
---|
| 5 | <meta name="generator" content= |
---|
| 6 | "Microsoft FrontPage 5.0"> |
---|
| 7 | <meta http-equiv="Content-Type" content= |
---|
| 8 | "text/html; charset=windows-1252"> |
---|
| 9 | <meta name="GENERATOR" content="Microsoft FrontPage 4.0"> |
---|
| 10 | <meta name="ProgId" content="FrontPage.Editor.Document"> |
---|
| 11 | |
---|
| 12 | <title>Header boost/cast.hpp Documentation</title> |
---|
| 13 | </head> |
---|
| 14 | |
---|
| 15 | <body bgcolor="#FFFFFF" text="#000000"> |
---|
| 16 | <h1><img src="../../boost.png" alt="boost.png (6897 bytes)" align= |
---|
| 17 | "middle" width="277" height="86">Header <a href= |
---|
| 18 | "../../boost/cast.hpp">boost/cast.hpp</a></h1> |
---|
| 19 | |
---|
| 20 | <h2><a name="Cast Functions">Cast Functions</a></h2> |
---|
| 21 | |
---|
| 22 | <p>The header <a href="../../boost/cast.hpp">boost/cast.hpp</a> provides <code> |
---|
| 23 | <a href="#Polymorphic_cast">polymorphic_cast</a> and</code> <a href= |
---|
| 24 | "#Polymorphic_cast"><code>polymorphic_downcast</code></a> function templates designed to |
---|
| 25 | complement the C++ built-in casts.</p> |
---|
| 26 | |
---|
| 27 | <p>The program <a href="cast_test.cpp">cast_test.cpp</a> can be used to |
---|
| 28 | verify these function templates work as expected.</p> |
---|
| 29 | |
---|
| 30 | <h3><a name="Polymorphic_cast">Polymorphic casts</a></h3> |
---|
| 31 | |
---|
| 32 | <p>Pointers to polymorphic objects (objects of classes which define at |
---|
| 33 | least one virtual function) are sometimes downcast or crosscast. |
---|
| 34 | Downcasting means casting from a base class to a derived class. |
---|
| 35 | Crosscasting means casting across an inheritance hierarchy diagram, such |
---|
| 36 | as from one base to the other in a <code>Y</code> diagram hierarchy.</p> |
---|
| 37 | |
---|
| 38 | <p>Such casts can be done with old-style casts, but this approach is |
---|
| 39 | never to be recommended. Old-style casts are sorely lacking in type |
---|
| 40 | safety, suffer poor readability, and are difficult to locate with search |
---|
| 41 | tools.</p> |
---|
| 42 | |
---|
| 43 | <p>The C++ built-in <code>static_cast</code> can be used for efficiently |
---|
| 44 | downcasting pointers to polymorphic objects, but provides no error |
---|
| 45 | detection for the case where the pointer being cast actually points to |
---|
| 46 | the wrong derived class. The <code>polymorphic_downcast</code> template retains |
---|
| 47 | the efficiency of <code>static_cast</code> for non-debug compilations, but for |
---|
| 48 | debug compilations adds safety via an assert() that a <code>dynamic_cast</code> |
---|
| 49 | succeeds.</p> |
---|
| 50 | |
---|
| 51 | <p>The C++ built-in <code>dynamic_cast</code> can be used for downcasts and |
---|
| 52 | crosscasts of pointers to polymorphic objects, but error notification in |
---|
| 53 | the form of a returned value of 0 is inconvenient to test, or worse yet, |
---|
| 54 | easy to forget to test. The throwing form of <code>dynamic_cast</code>, which |
---|
| 55 | works on references, can be used on pointers through the ugly expression |
---|
| 56 | &<code>dynamic_cast<T&>(*p)</code>, which causes undefined |
---|
| 57 | behavior if <code>p</code> is <code>0</code>. The <code>polymorphic_cast</code> |
---|
| 58 | template performs a <code>dynamic_cast</code> on a pointer, and throws an |
---|
| 59 | exception if the <code>dynamic_cast</code> returns 0.</p> |
---|
| 60 | |
---|
| 61 | <p>A <code>polymorphic_downcast</code> should be used for |
---|
| 62 | downcasts that you are certain should succeed. Error checking is |
---|
| 63 | only performed in translation units where <code>NDEBUG</code> is |
---|
| 64 | not defined, via |
---|
| 65 | <pre> assert( dynamic_cast<Derived>(x) == x ) |
---|
| 66 | </pre> where <code>x</code> is the source pointer. This approach |
---|
| 67 | ensures that not only is a non-zero pointer returned, but also |
---|
| 68 | that it is correct in the presence of multiple inheritance. |
---|
| 69 | Attempts to crosscast using <code>polymorphic_downcast</code> will |
---|
| 70 | fail to compile. |
---|
| 71 | <b>Warning:</b> Because <code>polymorphic_downcast</code> uses assert(), it |
---|
| 72 | violates the One Definition Rule (ODR) if NDEBUG is inconsistently |
---|
| 73 | defined across translation units. [See ISO Std 3.2] |
---|
| 74 | </p><p> |
---|
| 75 | For crosscasts, or when the success of a cast can only be known at |
---|
| 76 | runtime, or when efficiency is not important, |
---|
| 77 | <code>polymorphic_cast</code> is preferred. </p> |
---|
| 78 | |
---|
| 79 | <p>The C++ built-in <code>dynamic_cast</code> must be used to cast references |
---|
| 80 | rather than pointers. It is also the only cast that can be used to check |
---|
| 81 | whether a given interface is supported; in that case a return of 0 isn't |
---|
| 82 | an error condition.</p> |
---|
| 83 | |
---|
| 84 | <h3>polymorphic_cast and polymorphic_downcast synopsis</h3> |
---|
| 85 | |
---|
| 86 | <blockquote> |
---|
| 87 | <pre>namespace boost { |
---|
| 88 | |
---|
| 89 | template <class Derived, class Base> |
---|
| 90 | inline Derived polymorphic_cast(Base* x); |
---|
| 91 | // Throws: std::bad_cast if ( dynamic_cast<Derived>(x) == 0 ) |
---|
| 92 | // Returns: dynamic_cast<Derived>(x) |
---|
| 93 | |
---|
| 94 | template <class Derived, class Base> |
---|
| 95 | inline Derived polymorphic_downcast(Base* x); |
---|
| 96 | // Effects: assert( dynamic_cast<Derived>(x) == x ); |
---|
| 97 | // Returns: static_cast<Derived>(x) |
---|
| 98 | |
---|
| 99 | } |
---|
| 100 | </pre> |
---|
| 101 | </blockquote> |
---|
| 102 | |
---|
| 103 | <h3>polymorphic_downcast example</h3> |
---|
| 104 | |
---|
| 105 | <blockquote> |
---|
| 106 | <pre>#include <boost/cast.hpp> |
---|
| 107 | ... |
---|
| 108 | class Fruit { public: virtual ~Fruit(){}; ... }; |
---|
| 109 | class Banana : public Fruit { ... }; |
---|
| 110 | ... |
---|
| 111 | void f( Fruit * fruit ) { |
---|
| 112 | // ... logic which leads us to believe it is a Banana |
---|
| 113 | Banana * banana = boost::polymorphic_downcast<Banana*>(fruit); |
---|
| 114 | ... |
---|
| 115 | </pre> |
---|
| 116 | </blockquote> |
---|
| 117 | |
---|
| 118 | <h3>History</h3> |
---|
| 119 | |
---|
| 120 | <p><code>polymorphic_cast</code> was suggested by Bjarne Stroustrup in "The C++ |
---|
| 121 | Programming Language".<br> |
---|
| 122 | <code>polymorphic_downcast</code> was contributed by <a href= |
---|
| 123 | "../../people/dave_abrahams.htm">Dave Abrahams</a>.<code><br> |
---|
| 124 | An old |
---|
| 125 | numeric_cast</code> that was contributed by <a href= |
---|
| 126 | "../../people/kevlin_henney.htm">Kevlin Henney</a> is now superseeded by the <a href="../numeric/conversion/doc/index.html">Boost Numeric Conversion Library</a></p> |
---|
| 127 | <hr> |
---|
| 128 | |
---|
| 129 | <p>Revised |
---|
| 130 | <!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %B, %Y" startspan |
---|
| 131 | -->June 23, 2005<!--webbot bot="Timestamp" endspan i-checksum="30348" |
---|
| 132 | --></p> |
---|
| 133 | |
---|
| 134 | <p>© Copyright boost.org 1999. Permission to copy, use, modify, sell |
---|
| 135 | and distribute this document is granted provided this copyright notice |
---|
| 136 | appears in all copies. This document is provided "as is" without express |
---|
| 137 | or implied warranty, and with no claim as to its suitability for any |
---|
| 138 | purpose.</p> |
---|
| 139 | </body> |
---|
| 140 | </html> |
---|