c ++ create shared_ptr pour emstackr un object

Dans ma méthode, un object Player est créé comme suit:

Player player(fullName,age); 

Mon professeur nous a donné un morceau de code avec un constructeur qui prend un shared_ptr sur un object joueur.

 //constructor of the class SomeClass(const std::shared_ptr client, std::shared_ptr player) 

Disons que nous voulons appeler le constructeur de SomeClass et transmettre l’object lecteur créé sur la stack.

Est-il toujours sûr / possible / bon de créer un shared_ptr à partir d’un object de la stack?

Pour rendre la question plus compréhensible, disons que nous avons deux gros projets de code et que nous souhaitons les fusionner. Ainsi, une méthode d’un projet est appelée d’un autre projet. doit être connecté) ou devrions-nous simplement créer un shared_ptr pour l’object stack.

Pourquoi je ne suis pas sûr du résultat:

Que se passe-t-il si la scope dans laquelle l’object de stack est créé se termine mais que le shared_ptr est toujours utilisé et inversement?

L’object stack est supprimé lorsqu’il est hors de scope ou rest-t-il en vie car il existe toujours une référence à l’object (dans une autre classe cependant)?

Shared_ptr sort de la scope et tente de supprimer l’object. Peut-il le faire même si l’object stack le fait référence?

Note: Je sais que je pourrais juste utiliser ce qui suit et passer joueur

 shared_ptr player{ new Player {fullName,age} }; 

Est-il toujours sûr / possible / bon de créer un smart_ptr à partir d’un object de la stack?

En sécurité ? Seulement si vous pouvez garantir que la stack qui a créé cet object ne sera terminée qu’après tous les pseudos-propriétaires de shared_ptr .

Possible ? Bien sûr: passer le constructeur de shared_ptr un object deleter qui ne fait rien:

 auto sptr = shared_ptr(&player, [](Player *) {}); 

Quand le dernier shared_ptr est détruit, le deleter sera appelé et rien ne sera supprimé.

Bien Pas vraiment. Comme indiqué ci-dessus, la sécurité n’est pas universellement garantie dans un tel code. Selon votre structure de code, cela peut être légitime. Mais cela demande beaucoup de soin.

This SomeClass s’attend à revendiquer la propriété d’une ressource; c’est pourquoi il prend un shared_ptr . Vous mentez en lui passant un shared_ptr qui ne possède pas vraiment l’object qu’il référence. Cela signifie que vous et votre structure de code avez la responsabilité de ne pas violer la promesse que vous avez faite à SomeClass laquelle elle aurait le contrôle partagé sur la durée de vie de cet object.

Il n’est pas prudent de créer un pointeur partagé sur un object de stack, car celui-ci doit être détruit dès le retour de la fonction qui le contient. Les objects locaux sont alloués et désalloués de manière implicite et automatique et tenter d’intervenir implique certainement de nombreux types de comportement indéfini.

Le but d’un pointeur partagé est de gérer la durée de vie des objects créés dynamicment. Tant qu’il existe un pointeur partagé pointant sur un object, cet object doit toujours exister; lorsque le dernier pointeur partagé pointant vers un object est détruit, cet object est détruit.

Les objects Stack ont ​​une durée de vie fondamentalement différente: ils existent jusqu’à ce que le code sorte de l’étendue dans laquelle ils ont été créés, puis ils sont détruits.

Les deux notions de durée de vie sont incompatibles: aucun pointeur partagé ne peut garantir qu’un object de stack hors de scope existe toujours.

Alors ne mélangez pas les deux.

Coffre -fort est un mot fort. Cependant, vous pouvez rendre le code plus sûr en définissant un StackObjectSharedPtr, forçant le type instancié shared_ptr à inclure un “spécial” StackObjectDeleter.

 using PlayerStackSP = std::shared_ptr  ; class StackObjectDeleter { public: void operator () (void*) const {} }; Player player(fullName,age); std::shared_ptr player(&player, StackObjectDeleter()); 

StackObjectDeleter remplace default_delete en tant qu’object deleter. default_delete appelle simplement delete (ou delete []). Dans le cas de StackObjectDeleter, rien ne se passera.

Ceci est un pas de plus dans la réponse de @Nicol Bolas.

Est-il toujours sûr / possible / bon de créer un shared_ptr à partir d’un object de la stack?

Je suis d’accord avec @Nicolas Bolas sur le fait que ce n’est pas sans danger. Mais il peut être sûr de créer un shared_ptr à partir d’une copie d’un object de la stack

 shared_ptr playerPtr(new Player(player)); 

si le joueur est copiable bien sûr.