Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++11 Passing 'this' as paramenter for std::make_shared

I'm trying to pass 'this' to the constructor using std::make_shared

Example:

// headers
class A 
{
public:
   std::shared_ptr<B> createB();
}


class B 
{
private:
   std::shared_ptr<A> a;

public:
   B(std::shared_ptr<A>);
}


// source
std::shared_ptr<B> A::createB()
{
   auto b = std::make_shared<B>(this); // Compiler error (VS11 Beta)
   auto b = std::make_shared<B>(std::shared_ptr<A>(this)); // No compiler error, but doenst work
   return b;
}

However this does not work properly, any suggestions how I can properly pass this as an argument?

like image 249
RdR Avatar asked May 10 '12 12:05

RdR


People also ask

What is make_shared in C++?

Description. It constructs an object of type T passing args to its constructor, and returns an object of type shared_ptr that owns and stores a pointer to it.

Should I use make_shared?

make_shared is exception-safe. It uses the same call to allocate the memory for the control block and the resource, which reduces the construction overhead. If you don't use make_shared , then you have to use an explicit new expression to create the object before you pass it to the shared_ptr constructor.

Does make_shared call copy constructor?

Its seesm straight-forward -- make_shared needs to copy/move the unnamed MyClass() temp you created explicitly into the shared object space it allocates. It uses the move constructor if it can, or the copy constructor if there is no move constructor.

Should you pass shared pointers by reference?

Shared pointer parameter is passed by rvalue reference. Pass by value instead. Passing a shared pointer by rvalue reference is rarely necessary. Unless it's an implementation of move semantics for a shared pointer type itself, shared pointer objects can be safely passed by value.


1 Answers

I think what you probably want here is shared_from_this.

// headers
class A : std::enable_shared_from_this< A >
{
public:
   std::shared_ptr<B> createB();
}


class B 
{
private:
   std::shared_ptr<A> a;

public:
   B(std::shared_ptr<A>);
}


// source
std::shared_ptr<B> A::createB()
{
   return std::make_shared<B>( shared_from_this() );
}

Update to include comments from David Rodriguez:

Note that shared_from_this() should never be called on an object that isn't already managed by a shared_ptr. This is valid:

shared_ptr<A> a( new A );
a->createB();

While the following leads to undefined behaviour (attempting to call delete on a):

A a;
a.createB();
like image 114
Andrew Durward Avatar answered Sep 20 '22 22:09

Andrew Durward