web-dev-qa-db-fra.com

Est-il correct de retourner null shared_ptr?

Par exemple, il existe une fonction qui trouve un objet et renvoie shared_ptr si un objet est trouvé, et doit indiquer en quelque sorte qu'aucun objet n'a été trouvé.

std::vector<std::shared_ptr> Storage::objects;

std::shared_ptr<Object> Storage::findObject()
{
  if (objects.find)
  {
    return objects[x];
  }
  else
  {
    return nullptr;
  }
}

std::shared_ptr<Object> obj = Storage::findObject();
if (obj)
{
  print("found");
}
else
{
  print("not found");
}
  1. Est-il correct de retourner shared_ptr initialisé implicitement avec nullptr comme dans l'exemple supérieur? Cela fonctionnera, mais peut-il être fait de cette façon? Ou dois-je retourner la valeur par défaut shared_ptr construite à la place?

  2. Que se passe-t-il au cas où il serait faible_ptr? Quelle est la bonne façon de vérifier que le empty_ptr vide a été retourné? par la fonction faiblesse_ptr :: expirée ou existe-t-il d'autres moyens? Si la vérification par faiblesse_ptr :: expiré est le seul moyen, alors comment puis-je distinguer la fonction renvoyée d'un pointeur vide, ou l'objet vient d'être supprimé (environnement multi-thread)?

12
John Lock

Est-il correct de retourner shared_ptr initialisé implicitement avec nullptr comme dans l'exemple supérieur?

Oui, il est correct d'initialiser shared_ptr Avec nullptr. Il est également correct d'affecter nullptr à shared_ptr.

Ou dois-je retourner la valeur par défaut shared_ptr construite à la place?

Vous pouvez le faire des deux manières:

  1. renvoyant shared_ptr initialisé avec nullptr

    return shared_ptr<Object>(nullptr);
    
  2. renvoyant shared_ptr construit par défaut.

    return nullptr;
    

Les deux façons sont correctes et les deux ont le même effet. Vous pouvez utiliser ce que vous voulez.

Que se passe-t-il au cas où il serait faible_ptr? Quelle est la bonne façon de vérifier que le empty_ptr vide a été retourné? par la fonction faiblesse_ptr :: expirée ou existe-t-il d'autres moyens?

weak_ptr Devient nullptr (expire) chaque fois que le dernier shared_ptr Associé à l'objet est détruit.

La bonne façon de travailler avec weak_ptr Est de le convertir en shared_ptr Avec la méthode lock , puis de travailler avec le shared_ptr Créé. Dans ce cas, votre weak_ptr N'expirera pas tant que vous n'aurez pas ce nouveau shared_ptr. Si vous ne convertissez pas weak_ptr En shared_ptr, Votre weak_ptr Peut expirer à tout moment.

Et oui, avant de travailler avec shared_ptr Nouvellement créé, vous devez vérifier qu'il n'est pas nul, car weak_ptr A peut-être expiré avant de créer shared_ptr Avec lock méthode.

std::weak_ptr<Object> Storage::findObject();

...

std::weak_ptr  <Object> weak   = Storage::findObject();
std::shared_ptr<Object> shared = weak.lock();
if (shared) // check that weak was not expired when we did "shared = weak.lock()"
{
    // do something with shared, it will not expire.
}
12
anton_rh