Reputation: 3568
I'm just toying around with the smart pointers in the upcoming new c++ standard. However I fail to grasp the usage of the shared_from_this function. Here is what I have:
#include <iostream>
#include <memory>
class CVerboseBornAndDie2 : public std::enable_shared_from_this<CVerboseBornAndDie2>
{
public:
std::string m_Name;
CVerboseBornAndDie2(std::string name) : m_Name(name)
{
std::cout << m_Name << " (" << this << ") is born!" << std::endl;
}
virtual ~CVerboseBornAndDie2()
{
std::cout << m_Name << " (" << this << ") is dying!" << std::endl;
}
};
int main(){
CVerboseBornAndDie2* vbad = new CVerboseBornAndDie2("foo");
std::shared_ptr<CVerboseBornAndDie2> p = vbad->shared_from_this();
}
and it throws a std::bad_weak_ptr exception in the line
std::shared_ptr<CVerboseBornAndDie2> p = vbad->shared_from_this();
if I instead do
std::shared_ptr<CVerboseBornAndDie2> p(vbad);
it works and I can afterwards do
std::shared_ptr<CVerboseBornAndDie2> p2 = p.get()->shared_from_this();
so must the object belong to one shared_ptr before I can use shared_from_this? But how can I know this beforehand?
Upvotes: 9
Views: 6543
Reputation: 51255
To extend Charles answer, when you use enable_shared_from_this
you usually want something like below in order to guarantee that there exists a shared_ptr.
class my_class : public std::enable_shared_from_this<my_class>
{
public:
static std::shared_ptr<my_class> create() // can only be created as shared_ptr
{
return std::shared_ptr<my_class>(new my_class());
}
private
my_class(){} // don't allow non shared_ptr instances.
};
Upvotes: 16
Reputation: 791661
It is a precondition of using shared_from_this
that there must exist at least one shared_ptr
which owns the object in question. This means that you can only use shared_from_this
to retrieve a shared_ptr
that owns an object to which you have a reference or pointer, you cannot use it to find out if such an object is owned by a shared_ptr
.
You need to rework your design so that either you are guaranteed that any such object is being managed by a shared_ptr
or that you don't ever need to know or finally (and least desirably) you create some other way of managing this knowledge.
Upvotes: 22