I have a base View Controller class that uses enable_shared_from_this<>
class ViewController :
public std::enable_shared_from_this<ViewController>
{ // ...
};
and a child:
class GalleryViewController : public ViewController {
void updateGallery(float delta);
}
the problem arises, when I try to pass my current instance to 3rd party (say lambda function to be scheduled somewhere)
There is a (rare) condition that the instance (GalleryViewController
) will deallocate, so I cannot capture 'this' directly, I need to capture the shared group with shared_from_this()
:
void GalleryViewController::startUpdate()
{
auto updateFunction = [self = shared_from_this()](float delta)
{
return self->updateGallery(delta); // ERROR: ViewController don't have updateGallery() method!
};
scheduler->schedule(updateFunction); // takes lambda by value
}
The problem is that shared_from_this()
returns a shared_ptr<ViewController>
that doesn't have the updateGallery()
method.
I really hate to do dynamic_cast
(or even static in this case) it's a maintenance nightmare. And the code is ugly!
updateFunction = [self = shared_from_this()](float delta)
{
auto self2 = self.get();
auto self3 = (UIGalleryViewController*)self2;
return self3->updateGallery(delta);
};
Is there any default pattern to solve this problem? dynamic-type aware shared pointer? Should I double inherit the child class with enable_shared_from_this<GalleryViewController>
?
void GalleryViewController::startUpdate(bool shouldStart) { if (shouldStart == false) { updateFunction = [self = shared_from_this()](float delta) { return self->updateGallery(delta); // ERROR: ViewController don't have updateGallery() method! }; scheduler->schedule(updateFunction); // takes lambda by value }
The problem is that
shared_from_this()
returns ashared_ptr<ViewController>
that doesn't have theupdateGallery()
method.I really hate to do dynamic_cast (or even static in this case) its the maintenance nightmare. And the code is ugly!
That is what std::static_pointer_cast
and std::dynamic_pointer_cast
are for. You don't have to use .get()
to obtain a raw pointer before casting.
void GalleryViewController::startUpdate(bool shouldStart)
{
if (shouldStart == false) {
updateFunction = [self = std::static_pointer_cast<GalleryViewController>(shared_from_this())](float delta)
{
return self->updateGallery(delta);
};
scheduler->schedule(updateFunction); // takes lambda by value
}