c++ c++11 shared-ptr downcast

c++ - ¿Cómo se baja un std:: shared_ptr?



c++11 shared-ptr (3)

A partir de C ++ 11, §20.10.2.2.9 ( [util.smartptr.shared.cast] ) del estándar de C ++ especifica los equivalentes de static_cast , const_cast y dynamic_cast para que std::shared_ptr sea ​​el siguiente:

std::static_pointer_cast :

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

static_pointer_cast requiere que static_cast<T *>(r.get()) esté bien formado. Si r está vacío, se shared_ptr<T> un shared_ptr<T> vacío shared_ptr<T> ; de lo contrario, devuelve un puntero w comparte la propiedad con r donde w.get() == static_cast<T *>(r.get()) y 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 tiene requisitos y semántica similares a static_pointer_cast , excepto que se usa static_cast lugar de static_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 es un poco diferente ya que requiere que dynamic_cast<T *>(r.get()) esté bien formado y tenga una semántica bien definida. Si dynamic_cast<T *>(r.get()) es un valor distinto de cero, devuelve un puntero w comparte la propiedad con r donde w.get() == dynamic_cast<T *>(r.get()) y w.use_count() == r.use_count() , de lo contrario se shared_ptr<T> un shared_ptr<T> vacío shared_ptr<T> .

std::reinterpret_pointer_cast :

Para C ++ 17, N3920 (adoptado en Library Fundamentals TS en febrero de 2014 ) también propuso un std::reinterpret_pointer_cast similar al anterior, que solo requeriría reinterpret_cast<T *>((U *) 0) para estar bien formado y devuelve shared_ptr<T>(r, reinterpret_cast<typename shared_ptr<T>::element_type *>(r.get())) . Nota N3920 también cambió la redacción de los otros moldes shared_ptr y shared_ptr extendido para admitir matrices.

Considerar:

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. } }

(Tenga en cuenta que no puedo simplemente hacer std::shared_ptr<ChildOne>(static_cast<ChildOne*>(ptr.get())) , porque los recuentos de referencia no se comparten entre los dos shared_ptr s)


El equivalente shared_ptr de static_cast es static_pointer_cast , y el shared_ptr equivalente de dynamic_cast es dynamic_pointer_cast .


Esto debería funcionar:

if (ptr->IsChildOne()) { SomeClientExpectingAChildOne(std::static_pointer_cast<ChildOne>(ptr)); }