在具有虚拟析构函数的多态继承中使用 enable_shared_from_this

拉尔12

我有以下类结构来管理具有不同原型的回调:

class MethodHandlerBase: public std::enable_shared_from_this<MethodHandlerBase>{
public:
    virtual void operator()(void* data) = 0;
    virtual ~MethodHandlerBase(){}
};
   
class MethodHandlerA: public MethodHandlerBase{
private:
    MethodHandlerACallback cb;
public:
    MethodHandlerA(MethodHandlerACallback cb): cb(cb){}
    virtual void operator()(void* data);
};
    
class MethodHandlerB: public MethodHandlerBase{
private:
    MethodHandlerBCallback cb;
public:
    MethodHandlerB(MethodHandlerBCallback cb): cb(cb){}
    virtual void operator()(void* data);
};

在某些情况下MethodHandlerAMethodHandlerB可能this在传递给其他地方的 lambda 表达式中使用(包装在 shared_ptr 中),因此我需要确保在需要时正确删除它。因此我将std::enable_shared_from_this<MethodHandlerBase>继承添加到基类中。

但是我读到你通常std::enable_shared_from_this不能通过继承使用(除了使用模板,实际上它不再是真正的继承)。据我了解,这是由于可能错误地破坏了实例。在这种情况下,我会假设我的代码可以正常工作,因为它使用了虚拟析构函数(无论如何都需要)。

那么我的理论是否正确,或者还有其他std::enable_shared_from_this我不理解的关于继承的事情吗?

编辑

添加一个我打算使用它的简短示例,例如:

从课堂内部:

void MethodHandlerB::operator()(void* data){
    std::shared_ptr<MethodHandlerB> thisPtr = std::dynamic_pointer_cast<MethodHandlerB>(this->shared_from_this());
    putLamdaToSomeGlobalEventThing([thisPtr](){
        thisPtr->doSomething();
    });
}

和从外面

std::vector<MethodHandlerBase> vec{std::make_shared<MethodHandlerB>()};
阿瑟·塔卡

一些小点:

  • 您可以将共享指针移动到 lambda 中以避免原子递增和递减
  • 无需使用动态指针强制转换,因为您确定知道动态类型(而且无论如何您都不会检查结果是否为空!)
void MethodHandlerB::operator()(void* data){
    auto thisPtr = std::static_pointer_cast<MethodHandlerB>(this->shared_from_this());
    putLamdaToSomeGlobalEventThing([thisPtr = std::move(thisPtr)](){
        thisPtr->doSomething();
    });
}
  • 或者,您可以对this和 共享指针使用单独的捕获,从而完全避免强制转换:
void MethodHandlerB::operator()(void* data){
    putLamdaToSomeGlobalEventThing([this, thisPtr = shared_from_this()](){
        doSomething();
    });
}

编辑:正如其中一条评论指出的那样,如果您不shared_from_this()直接在基类上使用,那么最好仅从enable_shared_from_this派生类中派生。您可以这样做,因为 C++ 支持多重继承。

class MethodHandlerBase {
public:
    virtual void operator()(void* data) = 0;
    virtual ~MethodHandlerBase(){}
};
   
class MethodHandlerA: 
    public MethodHandlerBase,
    public std::enable_shared_from_this<MethodHandlerA>
{
private:
    MethodHandlerACallback cb;
public:
    MethodHandlerA(MethodHandlerACallback cb): cb(cb){}
    virtual void operator()(void* data);
};

void MethodHandlerA::operator()(void* data){
    putLamdaToSomeGlobalEventThing([self = shared_from_this()](){
        self->doSomething();
    });
}

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

从std :: enable_shared_from_this继承

std :: enable_shared_from_this:是否可以在析构函数中调用shared_from_this()?

如何在模板函数中使用enable_shared_from_this?

从 enable_shared_from_this 继承的目的是什么?

使用enable_shared_from_this的谷物库错误

从enable_shared_from_this继承并返回self的shared_ptr的类的子类

可以在不继承的情况下使用enable_shared_from_this吗?

如何在父类和子类中使用std :: enable_shared_from_this?

为继承enable_shared_from_this的类获取unique_ptr

enable_shared_from_this <S>什么时候有用?

std :: enable_shared_from_this与其他所有者

我们什么时候应该使用std :: enable_shared_from_this

为什么我们使用 enable_shared_from_this 模板?

为什么 std::enable_shared_from_this 不使用可变的 std::weak_ptr ?

是否有unique_from_this()?或者如何从从enable_shared_from_this继承的类中返回unique_ptr

pybind11,在使用 std::enable_shared_from_this 绑定 Trampolines 和多重继承时编译失败

尝试了解std :: enable_shared_from_this <T>,但使用它会导致bad_weak_ptr

如果未使用shared_ptr定义虚拟析构函数,有什么好处?

std :: enable_shared_from_this; 公共与私人

std :: enable_shared_from_this :: shared_from_this如何工作

C ++:使用仅具有属性的继承结构时需要实现虚拟析构函数吗?

“ enable_shared_from_this”的作用是什么?

Qt QObject和boost :: enable_shared_from_this

enable_shared_from_this 中的空弱指针

如何从boost :: enable_shared_from_this派生模板模板类?

具有shared_ptr的成员的C ++析构函数顺序

重载 -> shared_ptr<interface> 实例中的箭头运算符,接口中没有纯虚拟析构函数

如何在具有受保护的析构函数和公共销毁方法的3d派对类上使用shared_ptr

多态类中的虚拟析构函数