根据参考创建 shared_ptr
Create shared_ptr from reference
我是 C++ 的新手,这个接缝就像一个菜鸟问题,但我无法通过互联网上的其他资源解决它。
我正在尝试根据参考创建 shared_ptr。我有以下 Book
class:
#include <memory>
#include "Author.hpp"
class Book
{
public:
void setAuthor(const Author& t_author);
private:
std::shared_ptr<Author> m_author;
}
这是我的 Author
class:
#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);
}
但是如果我尝试编译它,我会得到:
Invalide conversion from const Author* to Author*
Invalide conversion from sizeof to const Author
你能告诉我我的代码有什么问题吗?我也对 weak_ptr 进行了同样的尝试,但这也不起作用。
尽管如此,您的错误源于以下事实:正在使用的 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));
}
如果你想复制使用std::make_shared
:
void Book::setAuthor(const Author& t_author)
{
m_author = std::make_shared<Author>(t_author);
}
但这是一个错误的设计,如果您希望保留传递对象的所有权,您应该将 std::shared_ptr
传递给您的函数而不是 const 引用:
void Book::setAuthor( std::shared_ptr<Author> t_author)
{
m_author = std::move( t_author );
}
这可能是未定义的行为。 shared_ptr
表示它指向的对象的 所有权 。在几乎所有可以想象的场景中,t_author
指的是一个现有的 Author
,它被其他东西拥有。几乎肯定会有两个地方试图破坏实例。
如果您必须为现有实例创建一个shared_ptr
,您可以考虑使用enable_shared_from_this,但这仅在t_author
是用 std::make_shared
创建的。如果是这种情况,您不妨更改函数以直接接受 shared_ptr
。或者,您可以使用不执行任何操作的自定义删除器创建 shared_ptr
。但在这一点上,使用 shared_ptr
没有任何好处,除了可能与某些接口的兼容性。
我是 C++ 的新手,这个接缝就像一个菜鸟问题,但我无法通过互联网上的其他资源解决它。
我正在尝试根据参考创建 shared_ptr。我有以下 Book
class:
#include <memory>
#include "Author.hpp"
class Book
{
public:
void setAuthor(const Author& t_author);
private:
std::shared_ptr<Author> m_author;
}
这是我的 Author
class:
#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);
}
但是如果我尝试编译它,我会得到:
Invalide conversion from const Author* to Author*
Invalide conversion from sizeof to const Author
你能告诉我我的代码有什么问题吗?我也对 weak_ptr 进行了同样的尝试,但这也不起作用。
尽管如此,您的错误源于以下事实:正在使用的 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));
}
如果你想复制使用std::make_shared
:
void Book::setAuthor(const Author& t_author)
{
m_author = std::make_shared<Author>(t_author);
}
但这是一个错误的设计,如果您希望保留传递对象的所有权,您应该将 std::shared_ptr
传递给您的函数而不是 const 引用:
void Book::setAuthor( std::shared_ptr<Author> t_author)
{
m_author = std::move( t_author );
}
这可能是未定义的行为。 shared_ptr
表示它指向的对象的 所有权 。在几乎所有可以想象的场景中,t_author
指的是一个现有的 Author
,它被其他东西拥有。几乎肯定会有两个地方试图破坏实例。
如果您必须为现有实例创建一个shared_ptr
,您可以考虑使用enable_shared_from_this,但这仅在t_author
是用 std::make_shared
创建的。如果是这种情况,您不妨更改函数以直接接受 shared_ptr
。或者,您可以使用不执行任何操作的自定义删除器创建 shared_ptr
。但在这一点上,使用 shared_ptr
没有任何好处,除了可能与某些接口的兼容性。