12
votes

Boost Shared_ptr: Différence entre opérateur = et réinitialiser?

Y a-t-il des différences entre les deux pièces de code ci-dessous? Est-ce que l'un d'entre eux est préférable à l'autre?

opérateur = strong> p> xxx pré>

réinitialiser strong>
p> xxx pré>

Remarque: j'ai besoin de définir le partage_ptr, puis de la définir dans une ligne différente, car je l'utilise dans un morceau de code comme: p>

boost::shared_ptr<Blah> foo;
try
{
  foo.reset...
}
foo...


4 Réponses :


16
votes

opérateur = attribue un partage_ptr à un partagée_ptr , tandis que réinitialiser fait un partagé_ptr Prends la propriété d'un pointeur. Donc, fondamentalement, il n'y a pas de différence entre les exemples que vous avez postés. Cela dit, vous ne devez y préférer ni utiliser make_shared : xxx

De plus, si possible, vous pouvez empêcher de déclarer un partagé_ptr sans initialisation en emballant le bloc d'essai dans une fonction distincte que renvoie simplement un partagé_ptr à l'objet nouvellement créé: xxx


2 commentaires

Pouvez-vous justifier votre commentaire que make_shared doit être préféré?


Construire sur un objet en utilisant Nouveau et initialisation d'un partagé_ptr avec il s'agit d'un processus en deux étapes. En théorie, la création de l'objet pourrait réussir, mais l'initialisation du partagée_ptr pourrait échouer, auquel cas vous alloueriez la mémoire, à moins que vous ne manipuliez explicitement ce cas. make_shared prend en charge cela pour vous. Selon le Documentation , il est également plus rapide.



3
votes

opérateur = prend un autre partagé_ptr en tant que paramètre créant ainsi une autre copie (et reculez le nombre de références) pendant que réinitialiser () prend un pointeur et éventuellement un Delier, donc en réalité créant un nouveau partage_ptr sur le dessus de la présente.

la réinitialisation est équivalente à (et probablement implémentée sous) xxx

opérateur = est susceptible d'être implémenté comme suit: xxx

Les deux fonctions sont similaires en ce qu'elles libèrent le contrôle de ce qu'ils contiennent déjà, le cas échéant et gèrent un pointeur différent à la place.


2 commentaires

RESET est également surchargé pour prendre un autre pointeur partagé, auquel cas il est équivalent à l'affectation.


Cashcow: Pourriez-vous expliquer le rôle de la ligne Shared_ptr partagé (autre); dans votre implémentation de opérateur = ?



2
votes

foo.reset (p) est défini pour être équivalent à partage_ptr (p) .swap (foo) . .

L'affectation est logiquement équivalente à la copie-échange et éventuellement mise en œuvre de cette façon. Donc FOO = Shared_Ptr (p); est équivalent à FOO.SWAP (Shared_PTR (P)) . Peut-être avec une copie supplémentaire là-bas si le compilateur a une très mauvaise journée.

Ainsi, dans les exemples que vous donnez, je ne pense pas qu'il y ait beaucoup à choisir entre les deux. Il pourrait y avoir d'autres cas où cela importe. Mais la réinitialisation est la même capture basée sur un modèle du type statique de P que le constructeur de modèle fait, à ce que l'obtention de la droite Delier est concerné, vous êtes couvert.

L'utilisation principale de l'affectation est lorsque vous souhaitez copier un partagé (code> partage_ptr ) pour partager la propriété du même objet. Bien sûr, cela fonctionne correctement lors de l'attribution d'un temporaire temporaire et si vous regardez les différentes surcharges réinitialiser , ils reflètent les différents constructeurs. Donc, je pense que vous pouvez obtenir les mêmes choses de toute façon.


0 commentaires

0
votes

Opérateur d'affectation Créez un nouvel objet partagé de l'existant, incrémentation du nombre de référence xxx pré>

pendant que l'appel de réinitialisation ne crée pas le nouvel objet partagé, mais plutôt une nouvelle propriété - attacher à Le nouveau pointe sous-jacent (via Objet de contrôle) P>

void CSharedObj::reset(Ptr pointee) noexcept
{
   //check if this is a last reference-detach from the previous ownership
   if(0==dec()) delete m_pControlObj;
   // create the ownership over the new pointee (refCnt = 1)
   m_pControlObj = new (std::nothrow) CControlObj(pointee);
}


0 commentaires