Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

enable_shared_from_this Vs Direct Assignment

Tags:

c++

c++11

Why should I use enable_shared_from_this as I can get the same effect via plain assignment also.

struct A : std::enable_shared_from_this<A> {
std::shared_ptr<A> getptr() {
    return shared_from_this();
 } 
};


int main () {
// What is the differentce between this code
 std::shared_ptr<A> p1 = make_shared<A>();
 std::shared_ptr<A> p2 = p1->getptr();

// Vs this

 std::shared_ptr<A> p1 = make_shared<A>();
 std::shared_ptr<A> p2 = p1;
}
like image 433
Deepak Kr Gupta Avatar asked Jan 05 '23 18:01

Deepak Kr Gupta


1 Answers

Because you can't get the "same" effect", at least not the one you may be thinking of.

There is no difference in the posted code methodologies, precisely because A inherits from std::enable_shared_from_this<A>. Both p1 and p2 are shared_ptr objects referring to the same concrete object (assuming only one of those sections is compiled for your tests, else you error on id name reuse).

std::enable_shared_from_this<T> allows you to acquire a std::shared_ptr<T> from some object, formally managed by some preexisting std::shared_ptr<T> of type T or derivative thereof, in locations where you have no std::shared_ptr<T> to the object to otherwise acquire, but need one for one reason or another. For example:

#include <iostream>
#include <memory>

struct A;

void foo(std::shared_ptr<A> arg)
{
}

struct A : std::enable_shared_from_this<A>
{
    void method()
    {
        foo(shared_from_this());
    }
};


int main ()
{
    auto a = std::make_shared<A>();
    a->method();
}

In the above example, foo requires a std::shared_ptr<A> as a parameter. From the body of A::method() no such mechanism exists without std::enable_shared_from_this<A> as a base. Without the std::enabled_shared_from_this<T> base, you would have to provide an alternative mechanism for passing the a shared pointer down the call chain until it reached foo. In short it would look something like this:

#include <iostream>
#include <memory>

struct A;

void foo(std::shared_ptr<A> arg)
{
}

struct A
{
    void method(std::shared_ptr<A> me)
    {
        foo(me);
    }
};


int main ()
{
    std::shared_ptr<A> a = std::make_shared<A>();
    a->method(a);
}

which is obviously dreadful and hideous. Further, there is no guarantee me in method is actually a std::shared_ptr<T> of this. Thus the standards committee blessed us with std::enable_shared_from_this<T>.

like image 104
WhozCraig Avatar answered Jan 15 '23 06:01

WhozCraig