Comment fait-on abattu un std::shared_ptr?
Considérer:
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 que je ne peux pas tout simplement faire un std::shared_ptr<ChildOne>(static_cast<ChildOne*>(ptr.get()))
, parce que le nombre de références ne sont pas partagés entre les deux shared_ptr
s)
Vous devez vous connecter pour publier un commentaire.
Cela devrait fonctionner:
std::static_pointer_cast
! Comment cela fonctionne, ne retournésshared_ptr
agir comme un proxy de sorte que les deux partagé les pointeurs de maintenir le même nombre de références ou pas?shared_ptr
a deux pointeurs, l'une pour l'objet partagé, et un pour le bloc avec le fort et le faible nombre de références. Deuxshared_ptr
s de types différents peuvent partager le fort et le faible nombre de références de blocs sans difficulté. Ma conjecture est qu'il est mis en œuvre avecstatic_pointer_cast
être unfriend
deshared_ptr
, mais bien sûr, votre application peut varier.shared_dynamic_cast
en Boost. Apparemmentdynamic_pointer_cast
est plus générique, cependant, car il fonctionne avec différents types de pointeurs (shared_ptr
, raw pointeurs,intrusive_ptr
, et potentiellement autre chose dans le futur).aliasing constructor
, (ref, ptr) créer un shared_pointer copie deref
mais pointant versptr
.La
shared_ptr
équivalent destatic_cast
eststatic_pointer_cast
, et lashared_ptr
équivalent dedynamic_cast
estdynamic_pointer_cast
.À partir de C++11, §20.10.2.2.9 ([util.smartptr.partagé.fonte]) de la norme C++ indique les équivalents de
static_cast
,const_cast
etdynamic_cast
pourstd::shared_ptr
comme suit:std::static_pointer_cast
:static_pointer_cast
nécessitestatic_cast<T *>(r.get())
d'être bien formés. Sir
est vide, un videshared_ptr<T>
est renvoyé, sinon retourne un pointeurw
le partage de la propriété avecr
oùw.get() == static_cast<T *>(r.get())
etw.use_count() == r.use_count()
.std::const_pointer_cast
:const_pointer_cast
a les mêmes exigences et la sémantique destatic_pointer_cast
, sauf queconst_cast
est utilisé à la place destatic_cast
.std::dynamic_pointer_cast
:dynamic_pointer_cast
est un peu différent car elle nécessitedynamic_cast<T *>(r.get())
d'être bien formés et ont bien défini de la sémantique. Sidynamic_cast<T *>(r.get())
est une valeur non nulle, retourne un pointeurw
le partage de la propriété avecr
oùw.get() == dynamic_cast<T *>(r.get())
etw.use_count() == r.use_count()
, sinon un videshared_ptr<T>
est retourné.std::reinterpret_pointer_cast
:Pour C++17, N3920 (adoptée en Bibliothèque Fondamentaux TS en février 2014) a également proposé un
std::reinterpret_pointer_cast
similaire à ci-dessus, qui n'aurait besoin que d'reinterpret_cast<T *>((U *) 0)
d'être bien formés et retourneshared_ptr<T>(r, reinterpret_cast<typename shared_ptr<T>::element_type *>(r.get()))
. Note N3920 également modifié le libellé de l'autreshared_ptr
jette et étendushared_ptr
à l'appui de tableaux.