]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> |
2 | <html> | |
3 | <head> | |
4 | <title>pointer_cast</title> | |
5 | <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" /> | |
6 | </head> | |
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> | |
19 | <pre> | |
20 | template<class T, class U> | |
21 | shared_ptr<T> static_pointer_cast(shared_ptr<U> const &r); | |
22 | </pre> | |
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> | |
30 | <blockquote> | |
31 | <pre> | |
32 | namespace boost { | |
33 | ||
34 | template<class T, class U> | |
35 | inline T* static_pointer_cast(U *ptr) | |
36 | { return static_cast<T*>(ptr); } | |
37 | ||
38 | template<class T, class U> | |
39 | inline T* dynamic_pointer_cast(U *ptr) | |
40 | { return dynamic_cast<T*>(ptr); } | |
41 | ||
42 | template<class T, class U> | |
43 | inline T* const_pointer_cast(U *ptr) | |
44 | { return const_cast<T*>(ptr); } | |
45 | ||
46 | template<class T, class U> | |
47 | inline T* reinterpret_pointer_cast(U *ptr) | |
48 | { return reinterpret_cast<T*>(ptr); } | |
49 | ||
50 | template<class T, class U> | |
51 | inline std::shared_ptr<T> static_pointer_cast(std::shared_ptr<U> const& r); | |
52 | ||
53 | template<class T, class U> | |
54 | inline std::shared_ptr<T> dynamic_pointer_cast(std::shared_ptr<U> const& r); | |
55 | ||
56 | template<class T, class U> | |
57 | inline std::shared_ptr<T> const_pointer_cast(std::shared_ptr<U> const& r); | |
58 | ||
59 | template<class T, class U> | |
60 | inline std::shared_ptr<T> reinterpret_pointer_cast(std::shared_ptr<U> const& r); | |
61 | ||
62 | template<class T, class U> | |
63 | inline std::unique_ptr<T> static_pointer_cast(std::unique_ptr<U>&& r); | |
64 | ||
65 | template<class T, class U> | |
66 | inline std::unique_ptr<T> dynamic_pointer_cast(std::unique_ptr<U>&& r); | |
67 | ||
68 | template<class T, class U> | |
69 | inline std::unique_ptr<T> const_pointer_cast(std::unique_ptr<U>&& r); | |
70 | ||
71 | template<class T, class U> | |
72 | inline std::unique_ptr<T> reinterpret_pointer_cast(std::unique_ptr<U>&& r); | |
73 | ||
74 | } // namespace boost | |
75 | </pre> | |
76 | </blockquote> | |
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> | |
79 | ||
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> | |
83 | ||
84 | <p>The pointer casts for <code>std::unique_ptr</code> are documented below.</p> | |
85 | ||
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> | |
89 | <blockquote> | |
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 | |
97 | object twice.</p> | |
98 | </blockquote> | |
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> | |
102 | <blockquote> | |
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> | |
107 | </blockquote> | |
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> | |
111 | <blockquote> | |
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> | |
115 | <ul> | |
116 | <li> | |
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> | |
119 | <li> | |
120 | Otherwise, <code>unique_ptr<T>()</code>.</li></ul> | |
121 | <p><b>Throws:</b> nothing.</p> | |
122 | </blockquote> | |
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> | |
126 | <blockquote> | |
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> | |
131 | </blockquote> | |
132 | ||
133 | <h2><a name="example">Example</a></h2> | |
134 | <blockquote> | |
135 | <pre> | |
136 | #include <boost/pointer_cast.hpp> | |
137 | #include <boost/shared_ptr.hpp> | |
138 | ||
139 | class base | |
140 | { | |
141 | public: | |
142 | ||
143 | virtual ~base() | |
144 | { | |
145 | } | |
146 | }; | |
147 | ||
148 | class derived: public base | |
149 | { | |
150 | }; | |
151 | ||
152 | template <class BasePtr> | |
153 | void check_if_it_is_derived(const BasePtr &ptr) | |
154 | { | |
155 | assert(boost::dynamic_pointer_cast<derived>(ptr) != 0); | |
156 | } | |
157 | ||
158 | int main() | |
159 | { | |
160 | <em>// Create a raw and a shared_ptr</em> | |
161 | ||
162 | base *ptr = new derived; | |
163 | boost::shared_ptr<base> sptr(new derived); | |
164 | ||
165 | <em>// Check that base pointer points actually to derived class</em> | |
166 | ||
167 | check_if_it_is_derived(ptr); | |
168 | check_if_it_is_derived(sptr); | |
169 | ||
170 | <em>// Ok!</em> | |
171 | ||
172 | delete ptr; | |
173 | return 0; | |
174 | }</pre> | |
175 | </blockquote> | |
176 | <p>The example demonstrates how the generic pointer casts help us create pointer | |
177 | independent code.</p> | |
178 | <hr /> | |
179 |