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
tovoid *
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
Why Is There Not an Std::Is_Struct Type Trait
C-Style Strings as Template Arguments
Error , Symbol 'Vector' Could Not Be Resolved
How to Make Transparent Window on Linux
Debugging in Linux Using Core Dumps
How to Measure CPU Time of a Specific Set of Threads
Find Out If String Ends with Another String in C++
About the Binary Compatibility of Linux
Create Window Without Title Bar
Headers Including Each Other in C++
Mpirun: Unrecognized Argument Mca
Segmentation Fault When Sending Struct Having Std::Vector Member
How to Evaluate Mathematical Expressions in C++
Using C++ Filestreams (Fstream), How to Determine the Size of a File