Je suis relativement nouveau sur C++ et cela semble être une question noob mais je n'ai pas pu le résoudre avec d'autres ressources sur Internet.
J'essaie de créer un shared_ptr à partir d'une référence. J'ai la classe Book
suivante:
#include <memory>
#include "Author.hpp"
class Book
{
public:
void setAuthor(const Author& t_author);
private:
std::shared_ptr<Author> m_author;
}
Et voici ma classe Author
:
#include <memory>
class Book;
class Author
{
public:
void addBook(const Book& t_book);
private:
std::vector<std::weak_ptr<Book>> m_books;
}
J'en ai assez de mettre en œuvre le Book::setAuthor
méthode comme ceci:
void Book::setAuthor(const Author& t_author)
{
m_author = std::shared_ptr<Author>(&t_author);
}
Mais si j'essaye de compiler ceci, j'obtiens:
Conversion invalide de const Author * en Author *
Conversion invalide de sizeof en const Author
Pouvez-vous me dire ce qui ne va pas avec mon code? J'ai également essayé la même chose avec le faiblesse_ptr mais cela ne fonctionne pas non plus.
Cependant, votre erreur provient du fait que le constructeur std::shared_ptr<Author>
Utilisé attend Author*
, Mais l'expression &t_author
Résulte en un objet de type const Author*
Une autre mauvaise chose:
void Book::setAuthor(const Author& t_author)
{
m_author = std::shared_ptr<Author>(&t_author);
}
Imaginez que vous appelez book.setAuthor(Author("Herb Sutter"));
, vous aurez un pointeur suspend car t_author
Cessera d'exister une fois cette fonction terminée.
Vous devez copier ou déplacer l'objet dans votre instance std::shared_ptr
. Utilisez std::make_shared<T>
Pour créer vos objets std::shared_ptr<T>
Dans la mesure du possible.
void Book::setAuthor(const Author& t_author)
{
m_author = std::make_shared<Author>(t_author);
}
Mieux encore:
void Book::setAuthor(Author t_author)
{
m_author = std::make_shared<Author>(std::move(t_author));
}
Si vous voulez faire une copie, utilisez std::make_shared
:
void Book::setAuthor(const Author& t_author)
{
m_author = std::make_shared<Author>(t_author);
}
mais ceci est une mauvaise conception, si vous prévoyez de conserver la propriété des objets passés, vous devez passer std::shared_ptr
à votre fonction au lieu de la référence const:
void Book::setAuthor( std::shared_ptr<Author> t_author)
{
m_author = std::move( t_author );
}
Il s'agit probablement d'un comportement non défini. shared_ptr
indique la propriété de l'objet vers lequel il pointe. Dans à peu près tous les scénarios imaginables, t_author
fait référence à un Author
existant qui appartient à autre chose. Il y aura presque sûrement deux emplacements qui tenteront de détruire l'instance.
Si vous devez créer un shared_ptr
à une instance existante, vous pouvez examiner l'utilisation de enable_shared_from_this , mais cela ne fonctionne que si t_author
a été créé avec std::make_shared
. Et si c'est le cas, vous pourriez aussi bien changer votre fonction pour accepter le shared_ptr
directement. Vous pouvez également créer un shared_ptr
avec un suppresseur personnalisé qui ne fait rien. Mais à ce stade, il n'y a rien à gagner à utiliser shared_ptr
, sauf peut-être la compatibilité avec certaines interfaces.