C++中基类继承 enable_shared_from_this 之后派生类无法使用 shared_from_this() 的解决方法

来源:互联网 发布:淘宝联盟的pid怎么设置 编辑:程序博客网 时间:2024/06/04 19:05

在很多情况下,我们会在基类中继承 std::enable_shared_from_this 来使得在该类的方法中能够使用 shared_ptr 托管的 this 指针。例如:

class Base : public std::enable_shared_from_this<Base> {public:    Base() { /* ... */ }    ~Base() { }    void method()    {        // ...        // 传递该类shared_ptr托管的this指针        function1(shared_from_this());    }    // ...private:    // ...};void function1(std::shared_ptr<Base> derived){    // ...}

但如果继承类使用 shared_from_this() 函数,就会发生错误。例如:

class Derived : public Base{public:    Derived() { /* ... */ }    ~Deried() { }    void method(std::shared_ptr<Derived> derived)    {        // ...        // 错误:不存在用户定义的从“std::shared_ptr<Base>”到“std::shared_ptr<Derived>”的适当转换        function2(shared_from_this());    }private:    // ...};void function2(std::shared_ptr<Derived> derived){    // ...}int main() {    std::shared_ptr<Derived> derived = std::make_shared<Derived>();    derived->method();    return 0;}

由于 function2 函数的参数类型为 std::shared_ptr<Derived>,故当 Derived 类调用方法 method 时,就需要向 function2 函数传递 shared_ptr 托管的 this 指针。但若是在此处使用 shared_from_this() 函数,就会发现编辑器返回了“不存在用户定义的从‘std::shared_ptr<Base>’到’std::shared_ptr<Derived>’的适当转换”的错误信息。

这是因为 Base 类在继承 enable_shared_from_this<T> 类时,向模板T传递的类型为Base,也就是 shared_from_this() 函数返回值类型被设定为了 std::shared_ptr<Base>。在 Derived 中调用 shared_from_this(),返回值不是std::shared_ptr<Derived>,而是std::shared_ptr<Base>。而我们知道,一般指针无法从基类隐性转换至派生类,这点对 shared_ptr 同样适用,所以就会发生以上错误。

这时我们就需要显性的对返回值类型进行转换。

解决方法是使用std::dynamic_pointer_cast<Derived>(shared_from_this())将shared_from_this()函数的返回值类型转换为Derived:

class Derived : public Base{public:    Derived() { /* ... */ }    ~Deried() { }    void method(std::shared_ptr<Derived> derived)    {        // ...        // shared_from_this()的返回值类型为std::shared_ptr<Base>,使用std::dynamic_pointer_cast<Derived>函数将其转为std::shared_ptr<Derived>类型        std::shared_ptr<Derived> pointer = std::dynamic_pointer_cast<Derived>(shared_from_this());        function2(pointer);    }private:    // ...};
0 0
原创粉丝点击