简体   繁体   中英

Wrong type in shared_from_this() in inherited class (is there a dyn.type-aware shared pointer?)

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 a shared_ptr<ViewController> that doesn't have the updateGallery() 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 whatstd::static_pointer_cast andstd::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
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM