forked from boostorg/smart_ptr
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathpointer_cast.html
183 lines (156 loc) · 8.29 KB
/
pointer_cast.html
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
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>pointer_cast</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
</head>
<body text="#000000" bgcolor="#ffffff" link="#0000ff" vlink="#0000ff">
<h1><img height="86" alt="boost.png (6897 bytes)" src="../../boost.png"
width="277" align="middle" border="0" />pointer_cast</h1>
<p>The pointer cast functions (<code>boost::static_pointer_cast</code> <code>boost::dynamic_pointer_cast</code>
<code>boost::reinterpret_pointer_cast</code> <code>boost::const_pointer_cast</code>)
provide a way to write generic pointer castings for raw pointers, <code>std::shared_ptr</code> and <code>std::unique_ptr</code>. The functions
are defined in <cite><a href="../../boost/pointer_cast.hpp">boost/pointer_cast.hpp</a>.</cite></p>
<p>There is test/example code in <cite><a href="test/pointer_cast_test.cpp">pointer_cast_test.cpp</a></cite>.</p>
<h2><a name="rationale">Rationale</a></h2>
<P>Boost smart pointers usually overload those functions to provide a mechanism to
emulate pointers casts. For example, <code>boost::shared_ptr<...></code> implements
a static pointer cast this way:</P>
<pre>
template<class T, class U>
shared_ptr<T> static_pointer_cast(shared_ptr<U> const &r);
</pre>
<p>Pointer cast functions from <cite><A href="../../boost/pointer_cast.hpp">boost/pointer_cast.hpp</A></CITE>
are overloads of <code>boost::static_pointer_cast</code>, <code>boost::dynamic_pointer_cast</code>,
<code>boost::reinterpret_pointer_cast</code> and <code>boost::const_pointer_cast</code>
for raw pointers, <code>std::shared_ptr</code> and <code>std::unique_ptr</code>. This way when developing
pointer type independent classes, for example, memory managers or shared memory compatible classes, the same
code can be used for raw and smart pointers.</p>
<h2><a name="synopsis">Synopsis</a></h2>
<blockquote>
<pre>
namespace boost {
template<class T, class U>
inline T* static_pointer_cast(U *ptr)
{ return static_cast<T*>(ptr); }
template<class T, class U>
inline T* dynamic_pointer_cast(U *ptr)
{ return dynamic_cast<T*>(ptr); }
template<class T, class U>
inline T* const_pointer_cast(U *ptr)
{ return const_cast<T*>(ptr); }
template<class T, class U>
inline T* reinterpret_pointer_cast(U *ptr)
{ return reinterpret_cast<T*>(ptr); }
template<class T, class U>
inline std::shared_ptr<T> static_pointer_cast(std::shared_ptr<U> const& r);
template<class T, class U>
inline std::shared_ptr<T> dynamic_pointer_cast(std::shared_ptr<U> const& r);
template<class T, class U>
inline std::shared_ptr<T> const_pointer_cast(std::shared_ptr<U> const& r);
template<class T, class U>
inline std::shared_ptr<T> reinterpret_pointer_cast(std::shared_ptr<U> const& r);
template<class T, class U>
inline std::unique_ptr<T> static_pointer_cast(std::unique_ptr<U>&& r);
template<class T, class U>
inline std::unique_ptr<T> dynamic_pointer_cast(std::unique_ptr<U>&& r);
template<class T, class U>
inline std::unique_ptr<T> const_pointer_cast(std::unique_ptr<U>&& r);
template<class T, class U>
inline std::unique_ptr<T> reinterpret_pointer_cast(std::unique_ptr<U>&& r);
} // namespace boost
</pre>
</blockquote>
<p>As you can see from the above synopsis, the pointer cast functions for raw pointers are just
wrappers around standard C++ cast operators.</p>
<p>The pointer casts for <code>std::shared_ptr</code> are aliases of the corresponding standard
functions with the same names and equivalent to <a href="shared_ptr.htm#static_pointer_cast">the
functions taking <code>boost::shared_ptr</code></a>.</p>
<p>The pointer casts for <code>std::unique_ptr</code> are documented below.</p>
<h3 id="static_pointer_cast">static_pointer_cast</h3>
<pre>template<class T, class U>
unique_ptr<T> static_pointer_cast(unique_ptr<U>&& r); // never throws</pre>
<blockquote>
<p><b>Requires:</b> The expression <code>static_cast<T*>( (U*)0 )</code>
must be well-formed.</p>
<p><b>Returns:</b> <code>unique_ptr<T>( static_cast<typename unique_ptr<T>::element_type*>(r.release()) )</code>.</p>
<p><b>Throws:</b> nothing.</p>
<p><b>Notes:</b> the seemingly equivalent expression
<code>unique_ptr<T>(static_cast<T*>(r.get()))</code>
will eventually result in undefined behavior, attempting to delete the same
object twice.</p>
</blockquote>
<h3 id="const_pointer_cast">const_pointer_cast</h3>
<pre>template<class T, class U>
unique_ptr<T> const_pointer_cast(unique_ptr<U>&& r); // never throws</pre>
<blockquote>
<p><b>Requires:</b> The expression <code>const_cast<T*>( (U*)0 )</code>
must be well-formed.</p>
<p><b>Returns:</b> <code>unique_ptr<T>( const_cast<typename unique_ptr<T>::element_type*>(r.release()) )</code>.</p>
<p><b>Throws:</b> nothing.</p>
</blockquote>
<h3 id="dynamic_pointer_cast">dynamic_pointer_cast</h3>
<pre>template<class T, class U>
unique_ptr<T> dynamic_pointer_cast(unique_ptr<U>&& r);</pre>
<blockquote>
<p><b>Requires:</b> The expression <code>dynamic_cast<T*>( (U*)0 )</code>
must be well-formed. <code>T</code> must have a virtual destructor.</p>
<p><b>Returns:</b></p>
<ul>
<li>
When <code>dynamic_cast<typename unique_ptr<T>::element_type*>(r.get())</code> returns a nonzero value,
<code>unique_ptr<T>(dynamic_cast<typename unique_ptr<T>::element_type*>(r.release()))</code>;</li>
<li>
Otherwise, <code>unique_ptr<T>()</code>.</li></ul>
<p><b>Throws:</b> nothing.</p>
</blockquote>
<h3 id="reinterpret_pointer_cast">reinterpret_pointer_cast</h3>
<pre>template<class T, class U>
unique_ptr<T> reinterpret_pointer_cast(unique_ptr<U>&& r); // never throws</pre>
<blockquote>
<p><b>Requires:</b> The expression <code>reinterpret_cast<T*>( (U*)0 )</code>
must be well-formed.</p>
<p><b>Returns:</b> <code>unique_ptr<T>( reinterpret_cast<typename unique_ptr<T>::element_type*>(r.release()) )</code>.</p>
<p><b>Throws:</b> nothing.</p>
</blockquote>
<h2><a name="example">Example</a></h2>
<blockquote>
<pre>
#include <boost/pointer_cast.hpp>
#include <boost/shared_ptr.hpp>
class base
{
public:
virtual ~base()
{
}
};
class derived: public base
{
};
template <class BasePtr>
void check_if_it_is_derived(const BasePtr &ptr)
{
assert(boost::dynamic_pointer_cast<derived>(ptr) != 0);
}
int main()
{
<em>// Create a raw and a shared_ptr</em>
base *ptr = new derived;
boost::shared_ptr<base> sptr(new derived);
<em>// Check that base pointer points actually to derived class</em>
check_if_it_is_derived(ptr);
check_if_it_is_derived(sptr);
<em>// Ok!</em>
delete ptr;
return 0;
}</pre>
</blockquote>
<p>The example demonstrates how the generic pointer casts help us create pointer
independent code.</p>
<hr />
<p>Copyright 2005 Ion Gaztañaga. Use, modification, and distribution are subject to
the Boost Software License, Version 1.0. (See accompanying file <a href="../../LICENSE_1_0.txt">
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>
</body>
</html>