我有以下类结构来管理具有不同原型的回调:
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);
};
在某些情况下MethodHandlerA
或MethodHandlerB
可能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>()};
一些小点:
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] 删除。
我来说两句