web-dev-qa-db-fra.com

Vérifiez null dans std :: shared_ptr

Je me demandais si je devais vérifier si sp est null avant de l'utiliser. Corrigez-moi si je me trompe, mais la création d'un alias n'augmentera pas le compteur de références et donc en entrant dans la méthode, nous travaillons avec un pointeur partagé dont nous ne savons pas si le pointeur incorporé a été réinitialisé auparavant. en supposant cela?

Class::MyFunction(std::shared_ptr<foo> &sp)
{    
    ...  
    sp->do_something();  
    ...  
}
35
Nostradamus

La plupart des pointeurs partagés sont exactement comme des pointeurs normaux à cet égard. Vous devez vérifier null. Selon la fonction, vous souhaiterez peut-être passer à

void myFunction( Foo const& foo );

et l'appeler en déréférençant le pointeur (ce qui repousse la responsabilité de s'assurer que le pointeur n'est pas nul pour l'appelant).

De plus, il est probablement mauvais de faire en sorte que la fonction prenne un pointeur partagé sauf il y a des sémantiques de propriété spéciales impliquées. Si la fonction va simplement utiliser le pointeur pour la durée de la fonction, ni en la modifiant ni en l'appropriant, un pointeur brut est probablement plus approprié, car il impose moins de contraintes à l'appelant. (Mais cela dépend vraiment beaucoup de ce que fait la fonction et de la raison pour laquelle vous utilisez des pointeurs partagés. Et bien sûr, le fait que vous ayez passé une référence non constante au pointeur partagé suppose que vous allez la modifier, donc passer un pointeur partagé pourrait être approprié.)

Enfin, différentes implémentations de pointeurs partagés rendent plus ou moins difficile la recherche de null. Avec C++ 11, vous pouvez utiliser std::shared_ptr, Et simplement le comparer à nullptr naturellement, comme vous vous en doutez. La mise en œuvre de Boost est cependant un peu cassée à cet égard; vous ne pouvez pas simplement le comparer à 0 ou NULL. Vous devez soit construire un boost::shared_ptr Vide pour la comparaison, soit appeler get dessus et comparer le pointeur brut résultant à 0 Ou NULL.

17
James Kanze

Vous devez considérer que std::shared_ptr est globalement toujours un pointeur (encapsulé dans une classe de type pointeur) et qu'il peut en effet être construit pour être en interne nullptr . Lorsque cela se produit, des expressions comme:

ptr->
*ptr

conduit à un comportement indéfini. Donc, oui, si vous vous attendez à ce que le pointeur soit également nullptr, alors vous devriez vérifier sa valeur avec:

ptr != nullptr

ou

!ptr

(grâce à son opérateur bool ).

46
Shoe

Il ne sert à rien de passer un shared_ptr comme référence.

Vous pouvez obtenir l'objet interne via boost::shared_ptr<T>.get() et vérifier nullptr

Également pertinent: passer à std :)

Edit : Voici l'implémentation: http://www.boost.org/doc/libs/1_55_0/boost/smart_ptr/shared_ptr .hpp Et voici un SO fil sur ref ou no ref: Dois-je passer un shared_ptr par référence?

Il utilise la sémantique de mouvement lorsque Cx11 et copie deux ints autrement, ce qui est plus lent que de passer une référence, mais quand est-ce que quelqu'un est à ce niveau d'optimisation?

3
Samuel

Il n'y a pas de réponse générale à cette question. Vous devez le traiter comme n'importe quel autre pointeur. Si vous ne savez pas si c'est nul, testez. Si vous croyez qu'il n'est jamais nul, assert() qu'il n'est pas nul et utilisez-le directement.

Le fait que vous ayez une référence à shared_ptr, ou même que vous avez un shared_ptr, n'a aucun impact ici.

2
Angew