从引用创建shared_ptr

Cil*_*nco 7 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;
}
Run Code Online (Sandbox Code Playgroud)

这是我的Author班级:

#include <memory>
class Book;

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

   private:
      std::vector<std::weak_ptr<Book>> m_books;
}
Run Code Online (Sandbox Code Playgroud)

我厌倦了实现这样的Book::setAuthor方法:

void Book::setAuthor(const Author& t_author)
{
   m_author = std::shared_ptr<Author>(&t_author);
}
Run Code Online (Sandbox Code Playgroud)

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

从const Author*到Author*的Invalide转换

从sizeof到const Author的Invalide转换

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

Whi*_*TiM 13

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


另一个错误的事:

void Book::setAuthor(const Author& t_author)
{
   m_author = std::shared_ptr<Author>(&t_author);
}
Run Code Online (Sandbox Code Playgroud)

想象一下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);
}
Run Code Online (Sandbox Code Playgroud)

更好的是:

void Book::setAuthor(Author t_author)
{
   m_author = std::make_shared<Author>(std::move(t_author));
}
Run Code Online (Sandbox Code Playgroud)

  • 后一种情况不会导致传递 `Author` 对象的复制吗? (3认同)

Sla*_*ica 5

如果要复制,请使用std::make_shared

void Book::setAuthor(const Author& t_author)
{
   m_author = std::make_shared<Author>(t_author);
}
Run Code Online (Sandbox Code Playgroud)

但这是一个错误的设计,如果您希望保留所传递对象的所有权,则应传递std::shared_ptr给函数而不是const引用:

void Book::setAuthor( std::shared_ptr<Author> t_author)
{
   m_author = std::move( t_author );
}
Run Code Online (Sandbox Code Playgroud)