How to disable std :: shared_ptr?

Consider:

struct SomethingThatsABase { virtual bool IsChildOne() const { return false; } virtual bool IsChildTwo() const { return false; } }; struct ChildOne : public SomethingThatsABase { virtual bool IsChildOne() const { return true; } }; struct ChildTwo : public SomethingThatsABase { virtual bool IsChildTwo() const { return true; } }; void SomeClientExpectingAChildOne(std::shared_ptr<ChildOne> const& ptrOne) { //Does stuff } void SomeClient(std::shared_ptr<SomethingThatsABase> const& ptr) { if (ptr->IsChildOne()) { SomeClientExpectingAChildOne(ptr); //Oops. //Hmm.. can't static_cast here, because we need a `shared_ptr` out of it. } } 

(Note that I cannot just do std::shared_ptr<ChildOne>(static_cast<ChildOne*>(ptr.get())) because then the reference count is not shared between the two shared_ptr s)

+46
c ++ c ++ 11 shared-ptr downcast
Jul 22 '11 at 20:18
source share
3 answers

This should work:

 if (ptr->IsChildOne()) { SomeClientExpectingAChildOne(std::static_pointer_cast<ChildOne>(ptr)); } 
+66
Jul 22 '11 at 20:22
source share

the equivalent of shared_ptr static_cast is static_pointer_cast , and the equivalent of shared_ptr dynamic_cast is dynamic_pointer_cast .

+31
Jul 22 '11 at 20:26
source share

Starting with C ++ 11, ยง20.10.2.2.9 ( [util.smartptr.shared.cast] ) of the C ++ standard defines the static_cast , const_cast and dynamic_cast equivalents for std::shared_ptr as follows:

std::static_pointer_cast :

 template <class T, class U> shared_ptr<T> static_pointer_cast(shared_ptr<U> const & r) noexcept; 

static_pointer_cast requires that static_cast<T *>(r.get()) be well formed. If r empty, an empty shared_ptr<T> is returned, otherwise it returns a pointer w to be shared with r , where w.get() == static_cast<T *>(r.get()) and w.use_count() == r.use_count() .

std::const_pointer_cast :

 template <class T, class U> shared_ptr<T> const_pointer_cast(shared_ptr<U> const & r) noexcept; 

const_pointer_cast has similar requirements and semantics for static_pointer_cast , except that static_cast used instead of const_cast .

std::dynamic_pointer_cast :

 template <class T, class U> shared_ptr<T> dynamic_pointer_cast(shared_ptr<U> const & r) noexcept; 

dynamic_pointer_cast slightly different, as dynamic_cast<T *>(r.get()) be well-formed and have well-defined semantics. If dynamic_cast<T *>(r.get()) is a non-zero value, returns a pointer w divide the property by r where w.get() == dynamic_cast<T *>(r.get()) and w.use_count() == r.use_count() , otherwise an empty shared_ptr<T> is returned.

std::reinterpret_pointer_cast :

For C ++ 17, N3920 (adopted by the TS Library Fundamentals in February 2014 ) also suggested a std::reinterpret_pointer_cast , similar to the one above, which would require reinterpret_cast<T *>((U *) 0) be good formed and returns shared_ptr<T>(r, reinterpret_cast<typename shared_ptr<T>::element_type *>(r.get())) . Note. The N3920 also reworded other shared_ptr translations and extended shared_ptr to support arrays.

+12
Apr 28 '16 at 11:02
source share



All Articles