我是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,但这也不起作用。
答案 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
没有任何好处,除了可能与某些接口的兼容性。