从引用创建shared_ptr

时间:2017-02-08 19:19:30

标签: c++ shared-ptr

我是C ++的新手,这个问题就像一个noob问题,但是我无法用互联网上的其他资源来解决它。

我正在尝试从引用创建shared_ptr。我关注了Book类:

#include <memory>
#include "Author.hpp"

class Book
{
   public:
      void setAuthor(const Author& t_author);

   private:
      std::shared_ptr<Author> m_author;
}

这是我的Author课程:

#include <memory>
class Book;

class Author
{
   public:
      void addBook(const Book& t_book);

   private:
      std::vector<std::weak_ptr<Book>> m_books;
}

我厌倦了如此实施Book::setAuthor方法:

void Book::setAuthor(const Author& t_author)
{
   m_author = std::shared_ptr<Author>(&t_author);
}

但如果我尝试编译这个,我得到:

  

从const Author *到Author *

的Invalide转换      

从sizeof到const Author

的Invalide转换

你能告诉我我的代码有什么问题吗?我也尝试使用weak_ptr,但这也不起作用。

3 个答案:

答案 0 :(得分:12)

但是,您的错误源于这样一个事实,即使用的std::shared_ptr<Author>构造函数需要Author*,但表达式&t_author会导致类型为const Author*的对象

另一个错误的事情:

void Book::setAuthor(const Author& t_author)
{
   m_author = std::shared_ptr<Author>(&t_author);
}

想象一下,调用book.setAuthor(Author("Herb Sutter"));,你会有一个悬空指针,因为t_author将在该函数完成后停止存在。

您需要将对象复制或移动到std::shared_ptr实例中。尽可能使用std::make_shared<T>创建std::shared_ptr<T>个对象。

void Book::setAuthor(const Author& t_author)
{
   m_author = std::make_shared<Author>(t_author);
}

更好的是:

void Book::setAuthor(Author t_author)
{
   m_author = std::make_shared<Author>(std::move(t_author));
}

答案 1 :(得分:5)

如果您想复制使用marging-right: 4px

std::make_shared

但这是一个错误的设计,如果你希望保留传递对象的所有权,你应该将void Book::setAuthor(const Author& t_author) { m_author = std::make_shared<Author>(t_author); } 传递给你的函数而不是const引用:

std::shared_ptr

答案 2 :(得分:2)

这可能是未定义的行为。 shared_ptr表示其指向的对象的所有权。在几乎所有可能的场景中,t_author指的是由其他东西拥有的现有Author。几乎肯定有两个地方试图破坏该实例。

如果必须为现有实例创建shared_ptr,您可以查看使用enable_shared_from_this,但这只适用于使用{创建t_author的情况{1}}。如果是这种情况,您也可以更改您的功能以直接接受std::make_shared。或者,您可以使用不执行任何操作的自定义删除工具创建shared_ptr。但是在那时,使用shared_ptr没有任何好处,除了可能与某些接口的兼容性。