I'm learning about c++11 features, specifically shared_ptr
, and I am having an issue with referring to this
and using it as a reference for other classes.
The reason for doing this is I have a Simulation
instance that is passed around to other instances within the simulation (e.g. Apple
) so they can themselves modify the simulation, or even remove themselves from the simulation.
In my more complex code I get a double free
error (when the program exists) which as I understand from here that I should not create a shared_ptr
twice on the same raw object. How do I pass this
to the Apple
object as a shared_ptr
when the Simulation class doesn't know that this
is already a shared_ptr
?
My thought is to pass the shared_ptr
in the initialisation argument but that seems redundant, e.g.:
// The argument is a std::shared_ptr<Simulation>
simulation->initSomethingElse(simulation);
Maybe I am trying to implement this in an unusual pattern, or maybe my understanding is not quite right? Maybe there is a nicer way of doing this instead?
I have a simplified example below:
#include <memory>
class Simulation;
class Apple {
public:
void init(std::shared_ptr<Simulation> simulation) {
this->simulation = simulation;
};
private:
std::shared_ptr<Simulation> simulation;
};
class Simulation {
public:
void initSomethingElse() {
auto apple = std::shared_ptr<Apple>(new Apple());
// incorrect second reference to the raw pointer
apple->init(std::shared_ptr<Simulation>(this));
};
};
int main() {
auto simulation = std::shared_ptr<Simulation>(new Simulation());
simulation->initSomethingElse();
return 0;
}
The first thing that comes to mind is to use enable_shared_from_this
: http://en.cppreference.com/w/cpp/memory/enable_shared_from_this
But the second thing that comes to mind is that the Simulation should be managing the lifetime of the Apple, so the Apple need not manage the lifetime of the Simulation. Therefore, you are better off having the Apple not hold a shared_ptr<Simulation>
- only main()
or some high-level function should manage the lifetime of the Simulation.
If you aren't careful you will end up with cyclic references. Don't assume every pointer in C++11 should be a shared_ptr.
Use enable_shared_from_this
so a function on the object can create a new shared_ptr
to itself. You'll want to do this instead of the apple->init(std::shared_ptr<Simulation>(this));
line that creates a second shared_ptr
to the Simulation
. You'll also want to rturn or save the apple
shared_ptr
somewhere, as at present the Apple
only exists while initSomethingElse()
is running, which doesn't seem very useful...?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With