1 <!DOCTYPE html PUBLIC
"-//W3C//DTD HTML 4.01 Transitional//EN">
4 <title>pointer_cast
</title>
5 <meta http-equiv=
"Content-Type" content=
"text/html; charset=iso-8859-1" />
7 <body text=
"#000000" bgcolor=
"#ffffff" link=
"#0000ff" vlink=
"#0000ff">
8 <h1><img height=
"86" alt=
"boost.png (6897 bytes)" src=
"../../boost.png"
9 width=
"277" align=
"middle" border=
"0" />pointer_cast
</h1>
10 <p>The pointer cast functions (
<code>boost::static_pointer_cast
</code> <code>boost::dynamic_pointer_cast
</code>
11 <code>boost::reinterpret_pointer_cast
</code> <code>boost::const_pointer_cast
</code>)
12 provide a way to write generic pointer castings for raw pointers,
<code>std::shared_ptr
</code> and
<code>std::unique_ptr
</code>. The functions
13 are defined in
<cite><a href=
"../../boost/pointer_cast.hpp">boost/pointer_cast.hpp
</a>.
</cite></p>
14 <p>There is test/example code in
<cite><a href=
"test/pointer_cast_test.cpp">pointer_cast_test.cpp
</a></cite>.
</p>
15 <h2><a name=
"rationale">Rationale
</a></h2>
16 <P>Boost smart pointers usually overload those functions to provide a mechanism to
17 emulate pointers casts. For example,
<code>boost::shared_ptr
<...
></code> implements
18 a static pointer cast this way:
</P>
20 template
<class T, class U
>
21 shared_ptr
<T
> static_pointer_cast(shared_ptr
<U
> const
&r);
23 <p>Pointer cast functions from
<cite><A href=
"../../boost/pointer_cast.hpp">boost/pointer_cast.hpp
</A></CITE>
24 are overloads of
<code>boost::static_pointer_cast
</code>,
<code>boost::dynamic_pointer_cast
</code>,
25 <code>boost::reinterpret_pointer_cast
</code> and
<code>boost::const_pointer_cast
</code>
26 for raw pointers,
<code>std::shared_ptr
</code> and
<code>std::unique_ptr
</code>. This way when developing
27 pointer type independent classes, for example, memory managers or shared memory compatible classes, the same
28 code can be used for raw and smart pointers.
</p>
29 <h2><a name=
"synopsis">Synopsis
</a></h2>
34 template
<class T, class U
>
35 inline T* static_pointer_cast(U *ptr)
36 { return static_cast
<T*
>(ptr); }
38 template
<class T, class U
>
39 inline T* dynamic_pointer_cast(U *ptr)
40 { return dynamic_cast
<T*
>(ptr); }
42 template
<class T, class U
>
43 inline T* const_pointer_cast(U *ptr)
44 { return const_cast
<T*
>(ptr); }
46 template
<class T, class U
>
47 inline T* reinterpret_pointer_cast(U *ptr)
48 { return reinterpret_cast
<T*
>(ptr); }
50 template
<class T, class U
>
51 inline std::shared_ptr
<T
> static_pointer_cast(std::shared_ptr
<U
> const
& r);
53 template
<class T, class U
>
54 inline std::shared_ptr
<T
> dynamic_pointer_cast(std::shared_ptr
<U
> const
& r);
56 template
<class T, class U
>
57 inline std::shared_ptr
<T
> const_pointer_cast(std::shared_ptr
<U
> const
& r);
59 template
<class T, class U
>
60 inline std::shared_ptr
<T
> reinterpret_pointer_cast(std::shared_ptr
<U
> const
& r);
62 template
<class T, class U
>
63 inline std::unique_ptr
<T
> static_pointer_cast(std::unique_ptr
<U
>&& r);
65 template
<class T, class U
>
66 inline std::unique_ptr
<T
> dynamic_pointer_cast(std::unique_ptr
<U
>&& r);
68 template
<class T, class U
>
69 inline std::unique_ptr
<T
> const_pointer_cast(std::unique_ptr
<U
>&& r);
71 template
<class T, class U
>
72 inline std::unique_ptr
<T
> reinterpret_pointer_cast(std::unique_ptr
<U
>&& r);
77 <p>As you can see from the above synopsis, the pointer cast functions for raw pointers are just
78 wrappers around standard C++ cast operators.
</p>
80 <p>The pointer casts for
<code>std::shared_ptr
</code> are aliases of the corresponding standard
81 functions with the same names and equivalent to
<a href=
"shared_ptr.htm#static_pointer_cast">the
82 functions taking
<code>boost::shared_ptr
</code></a>.
</p>
84 <p>The pointer casts for
<code>std::unique_ptr
</code> are documented below.
</p>
86 <h3 id=
"static_pointer_cast">static_pointer_cast
</h3>
87 <pre>template
<class T, class U
>
88 unique_ptr
<T
> static_pointer_cast(unique_ptr
<U
>&& r); // never throws
</pre>
90 <p><b>Requires:
</b> The expression
<code>static_cast
<T*
>( (U*)
0 )
</code>
91 must be well-formed.
</p>
92 <p><b>Returns:
</b> <code>unique_ptr
<T
>( static_cast
<typename unique_ptr
<T
>::element_type*
>(r.release()) )
</code>.
</p>
93 <p><b>Throws:
</b> nothing.
</p>
94 <p><b>Notes:
</b> the seemingly equivalent expression
95 <code>unique_ptr
<T
>(static_cast
<T*
>(r.get()))
</code>
96 will eventually result in undefined behavior, attempting to delete the same
99 <h3 id=
"const_pointer_cast">const_pointer_cast
</h3>
100 <pre>template
<class T, class U
>
101 unique_ptr
<T
> const_pointer_cast(unique_ptr
<U
>&& r); // never throws
</pre>
103 <p><b>Requires:
</b> The expression
<code>const_cast
<T*
>( (U*)
0 )
</code>
104 must be well-formed.
</p>
105 <p><b>Returns:
</b> <code>unique_ptr
<T
>( const_cast
<typename unique_ptr
<T
>::element_type*
>(r.release()) )
</code>.
</p>
106 <p><b>Throws:
</b> nothing.
</p>
108 <h3 id=
"dynamic_pointer_cast">dynamic_pointer_cast
</h3>
109 <pre>template
<class T, class U
>
110 unique_ptr
<T
> dynamic_pointer_cast(unique_ptr
<U
>&& r);
</pre>
112 <p><b>Requires:
</b> The expression
<code>dynamic_cast
<T*
>( (U*)
0 )
</code>
113 must be well-formed.
<code>T
</code> must have a virtual destructor.
</p>
114 <p><b>Returns:
</b></p>
117 When
<code>dynamic_cast
<typename unique_ptr
<T
>::element_type*
>(r.get())
</code> returns a nonzero value,
118 <code>unique_ptr
<T
>(dynamic_cast
<typename unique_ptr
<T
>::element_type*
>(r.release()))
</code>;
</li>
120 Otherwise,
<code>unique_ptr
<T
>()
</code>.
</li></ul>
121 <p><b>Throws:
</b> nothing.
</p>
123 <h3 id=
"reinterpret_pointer_cast">reinterpret_pointer_cast
</h3>
124 <pre>template
<class T, class U
>
125 unique_ptr
<T
> reinterpret_pointer_cast(unique_ptr
<U
>&& r); // never throws
</pre>
127 <p><b>Requires:
</b> The expression
<code>reinterpret_cast
<T*
>( (U*)
0 )
</code>
128 must be well-formed.
</p>
129 <p><b>Returns:
</b> <code>unique_ptr
<T
>( reinterpret_cast
<typename unique_ptr
<T
>::element_type*
>(r.release()) )
</code>.
</p>
130 <p><b>Throws:
</b> nothing.
</p>
133 <h2><a name=
"example">Example
</a></h2>
136 #include
<boost/pointer_cast.hpp
>
137 #include
<boost/shared_ptr.hpp
>
148 class derived: public base
152 template
<class BasePtr
>
153 void check_if_it_is_derived(const BasePtr
&ptr)
155 assert(boost::dynamic_pointer_cast
<derived
>(ptr) !=
0);
160 <em>// Create a raw and a shared_ptr
</em>
162 base *ptr = new derived;
163 boost::shared_ptr
<base
> sptr(new derived);
165 <em>// Check that base pointer points actually to derived class
</em>
167 check_if_it_is_derived(ptr);
168 check_if_it_is_derived(sptr);
176 <p>The example demonstrates how the generic pointer casts help us create pointer
177 independent code.
</p>
179 <p>Copyright
2005 Ion GaztaƱaga. Use, modification, and distribution are subject to
180 the Boost Software License, Version
1.0. (See accompanying file
<a href=
"../../LICENSE_1_0.txt">
181 LICENSE_1_0.txt
</a> or a copy at
<<a href=
"http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt
</a>>.)
</p>