web-dev-qa-db-fra.com

Comment dupliquer correctement un objet étant donné son shared_ptr

J'essaie de faire un doublon d'un objet d'une classe personnalisée Event. J'ai un pointeur partagé vers l'objet que j'ai obtenu de son allocation:

std::shared_ptr<Event> e = std::make_shared<Event>();

Afin d'obtenir un vrai doublon de e (pas seulement une copie du pointeur), j'ai essayé:

std::shared_ptr<Event> o = std::make_shared<Event>(*e);

Mais je ne suis pas sûr que ce soit la bonne façon car il semble que si je supprime e il supprime également o...

Btw, je n'ai pas défini de constructeur de copie Event::Event(const Event &orig) mais à ma connaissance ce n'est pas nécessaire car le compilateur fournit un constructeur de copie par défaut. La classe d'événements contient uniquement des variables et aucun autre pointeur.

18
Marc

std::make_shared n'est qu'une simple fonction de modèle qui crée les objets, en passant tous les arguments au constructeur:

template<class T, class... Args>
shared_ptr<T> make_shared(Args&&... args)
{
  return shared_ptr<T>( new T( std::forward<Args>( args )... ) );
}

Dans votre cas particulier:

std::shared_ptr<Event> o = std::make_shared<Event>(*e);

l'objet est copié.

Si votre code est tel:

void foo() {
    // create new object using default constructor
    std::shared_ptr<Event> e = std::make_shared<Event>();
    // create new object using copy constructor constructor
    std::shared_ptr<Event> o = std::make_shared<Event>(*e);
}

alors bien sûr les deux objets sont détruits, lorsqu'ils sortent du cadre.

12
BЈовић

Ce que vous avez essayé devrait fonctionner correctement, si le type dynamique de *e Est Event, et non une classe dérivée de Event. (Si *e Est en fait un objet dérivé de Event, vous allez créer un nouveau Event (pas le type dérivé) comme copie de la partie classe de base de *e C'est-à-dire que vous "découperez" *e).

Puisque vous créez e à l'aide de make_shared<Event>() vous savez que dans ce cas il s'agit vraiment d'un Event, donc std::make_shared<Event>(*e) devrait faire un nouveau shared_ptr qui possède une copie de *e.

5
Jonathan Wakely