The pointer cast functions (boost::static_pointer_cast
boost::dynamic_pointer_cast
boost::reinterpret_pointer_cast
boost::const_pointer_cast
)
provide a way to write generic pointer castings for raw pointers, std::shared_ptr
and std::unique_ptr
. The functions
are defined in boost/pointer_cast.hpp.
There is test/example code in pointer_cast_test.cpp.
Boost smart pointers usually overload those functions to provide a mechanism to
emulate pointers casts. For example, boost::shared_ptr<...>
implements
a static pointer cast this way:
template<class T, class U> shared_ptr<T> static_pointer_cast(shared_ptr<U> const &r);
Pointer cast functions from boost/pointer_cast.hpp
are overloads of boost::static_pointer_cast
, boost::dynamic_pointer_cast
,
boost::reinterpret_pointer_cast
and boost::const_pointer_cast
for raw pointers, std::shared_ptr
and std::unique_ptr
. 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.
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
As you can see from the above synopsis, the pointer cast functions for raw pointers are just wrappers around standard C++ cast operators.
The pointer casts for std::shared_ptr
are aliases of the corresponding standard
functions with the same names and equivalent to the
functions taking boost::shared_ptr
.
The pointer casts for std::unique_ptr
are documented below.
template<class T, class U> unique_ptr<T> static_pointer_cast(unique_ptr<U>&& r); // never throws
Requires: The expression
static_cast<T*>( (U*)0 )
must be well-formed.Returns:
unique_ptr<T>( static_cast<typename unique_ptr<T>::element_type*>(r.release()) )
.Throws: nothing.
Notes: the seemingly equivalent expression
unique_ptr<T>(static_cast<T*>(r.get()))
will eventually result in undefined behavior, attempting to delete the same object twice.
template<class T, class U> unique_ptr<T> const_pointer_cast(unique_ptr<U>&& r); // never throws
Requires: The expression
const_cast<T*>( (U*)0 )
must be well-formed.Returns:
unique_ptr<T>( const_cast<typename unique_ptr<T>::element_type*>(r.release()) )
.Throws: nothing.
template<class T, class U> unique_ptr<T> dynamic_pointer_cast(unique_ptr<U>&& r);
Requires: The expression
dynamic_cast<T*>( (U*)0 )
must be well-formed.T
must have a virtual destructor.Returns:
- When
dynamic_cast<typename unique_ptr<T>::element_type*>(r.get())
returns a nonzero value,unique_ptr<T>(dynamic_cast<typename unique_ptr<T>::element_type*>(r.release()))
;- Otherwise,
unique_ptr<T>()
.Throws: nothing.
template<class T, class U> unique_ptr<T> reinterpret_pointer_cast(unique_ptr<U>&& r); // never throws
Requires: The expression
reinterpret_cast<T*>( (U*)0 )
must be well-formed.Returns:
unique_ptr<T>( reinterpret_cast<typename unique_ptr<T>::element_type*>(r.release()) )
.Throws: nothing.
#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() { // Create a raw and a shared_ptr base *ptr = new derived; boost::shared_ptr<base> sptr(new derived); // Check that base pointer points actually to derived class check_if_it_is_derived(ptr); check_if_it_is_derived(sptr); // Ok! delete ptr; return 0; }
The example demonstrates how the generic pointer casts help us create pointer independent code.
Copyright 2005 Ion Gaztaņaga. Use, modification, and distribution are subject to the Boost Software License, Version 1.0. (See accompanying file LICENSE_1_0.txt or a copy at <http://www.boost.org/LICENSE_1_0.txt>.)