I'm relativly new to C++ and this seams like a noob question but I wasn't able to solve it with other resources on the internet.
I'm trying to create a shared_ptr from a reference. I have following Book
class:
#include <memory>
#include "Author.hpp"
class Book
{
public:
void setAuthor(const Author& t_author);
private:
std::shared_ptr<Author> m_author;
}
And this is my Author
class:
#include <memory>
class Book;
class Author
{
public:
void addBook(const Book& t_book);
private:
std::vector<std::weak_ptr<Book>> m_books;
}
I tired to implement the Book::setAuthor
method like so:
void Book::setAuthor(const Author& t_author)
{
m_author = std::shared_ptr<Author>(&t_author);
}
But if I try to compile this I get:
Invalide conversion from const Author* to Author*
Invalide conversion from sizeof to const Author
Can you please tell me what is wrong with my code? I also tried the same with the weak_ptr but this does not work either.
This is likely undefined behavior.
shared_ptr
indicates ownership of the object it points to. In just about every conceivable scenario,t_author
refers to an existingAuthor
that is owned by something else. There will almost surely be two locations that try to destroy the instance.If you must create a
shared_ptr
to an existing instance, you can look into using enable_shared_from_this, but this only works ift_author
was created withstd::make_shared
. And if this is the case, you might as well change your function to accept theshared_ptr
directly. Alternatively, you can create ashared_ptr
with a custom deleter that does nothing. But at that point, there is nothing to gain from usingshared_ptr
, except perhaps compatibility with some interface.Though, your error stems from the fact that the
std::shared_ptr<Author>
constructor in use expectsAuthor*
, but the expression&t_author
results to an object of typeconst Author*
Another wrong thing:
Imagine calling
book.setAuthor(Author("Herb Sutter"));
, you will have a dangling pointer becauset_author
will cease to exist after that function completes.You need to copy or move the object into your
std::shared_ptr
instance. Usestd::make_shared<T>
to create yourstd::shared_ptr<T>
objects whenever possible.Better still:
If you want to make a copy use
std::make_shared
:but this is a wrong design, if you expect to keep ownership of passed objects you should pass
std::shared_ptr
to your function instead of const reference: