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));
}