Why Shared_From_This Can't Be Used in Constructor from Technical Standpoint

Why shared_from_this can't be used in constructor from technical standpoint?

The reason is simple: in object X, enable_shared_from_this works by initialising a hidden weak_ptr with a copy of the first shared_ptr which points to object X. However, for a shared_ptr to be able to point to X, X must already exist (it must be already constructed). Therefore, while the constructor of X is running, there is yet no shared_ptr which enable_shared_from_this could use.

Take this piece of code:

std::shared_ptr<Person> p(new Person());

Before the constructor of p (of the shared_ptr) is even called, its argument must be evaluated. That argument is the expression new Person(). Therefore, the constructor of Person runs before the constructor of p has even begun—before there is any shared_ptr object to which enable_shared_from_this could bind.

pass shared_ptr i.e. shared_from_this() as a void*

You cannot call shared_from_this in a contructor. You also don't need to because what you wanted was void*. this implicitly converts to void*. You don't need access to the shared pointer in the first place.

This is very simple:

A(): mCobj{5, this} {

Note that if you make a copy of A, then the copy will point to the object it was copied from. Consider whether this is what you want, and if not, then change the copy and move constructor and assignment operator to behave as you would want them to behave.

I am not sure how can I convert a shared_ptr to void *

You can use the member function get. The resulting pointer implicitly converts to void*.

std::bad_weak_ptr exception when using shared_from_this

You can't use shared_from_this in constructor since no shared_ptr is assigned yet. See this Why shared_from_this can't be used in constructor from technical standpoint?

However when the object is constructed and there is any shared_ptr associated with the instance, you are able to call shared_from_this as usual.

What is the usefulness of `enable_shared_from_this`?

It enables you to get a valid shared_ptr instance to this, when all you have is this. Without it, you would have no way of getting a shared_ptr to this, unless you already had one as a member. This example from the boost documentation for enable_shared_from_this:

class Y: public enable_shared_from_this<Y>
{
public:

shared_ptr<Y> f()
{
return shared_from_this();
}
}

int main()
{
shared_ptr<Y> p(new Y);
shared_ptr<Y> q = p->f();
assert(p == q);
assert(!(p < q || q < p)); // p and q must share ownership
}

The method f() returns a valid shared_ptr, even though it had no member instance. Note that you cannot simply do this:

class Y: public enable_shared_from_this<Y>
{
public:

shared_ptr<Y> f()
{
return shared_ptr<Y>(this);
}
}

The shared pointer that this returned will have a different reference count from the "proper" one, and one of them will end up losing and holding a dangling reference when the object is deleted.

enable_shared_from_this has become part of C++ 11 standard. You can also get it from there as well as from boost.

Constructing an object other than specified parameters NOT giving me errors

You can prevent this implicit conversion by declaring the Foo constructor explicit

explicit Foo(int x) : y { x } { }

in main this would require the caller to change their obj_2 instantiation to

Bar obj_2 { Foo{2021} };


Related Topics



Leave a reply



Submit