当前位置: 首页 > article >正文

shared_ptr子类指针转换成父类指针

假设有如下应用场景:

class Base
{
public:
    void addChild(std::shared_ptr<Base>& child)
    {
        ...
    }
}

class Derived : public Base
{}

int main()
{
    Base a;
    std::shared_ptr<Derived> b = std::make_shared<Derived>();
    a.addChild(b);  // Error
}

该代码中声明了两个类,Base类是基类,带有一个接受一个Base类型智能指针引用作为入参的成员函数addChild,而Derived类是Base类的派生类.

当我们在main函数中创建了一个Derived类的共享对象shared_ptr<Derived>时,不同于裸指针Derived*与Base*,它实际上与shared_ptr<Base>会被视作是不同的类型,因此Base类的成员函数addChild无法直接接受b的引用作为入参.那怎么办?

第一种解决方案也是最简单的一种解决方案是先把b转换成基类类型的智能指针.

int main()
{
    Base a;
    std::shared_ptr<Derived> b = std::make_shared<Derived>();
    std::shared_ptr<Base> c = b;  // convert to base class
    a.addChild(c);  // OK
}

还有一种解决方案, 我们可能会想到可以重新声明一个shared_ptr<Base>类型的智能指针,将它内部的指针指向Derived,这样就可以把它传给addChild函数了,但是对智能指针直接赋值肯定是不行的,因为shared_ptr内部有一个计数器,当计数器归零时它会delete内部真正的指针,把已经被一个智能指针管理的对象直接赋值给另一个智能指针会导致两个智能指针析构时重复delete对象,导致程序崩溃.

int main()
{
    std::shared_ptr<Derived> b = std::make_shared<Derived>();
    std::shared_ptr<Base> c = std::shared_ptr<Base>(b.get());  // Error
}

解决方案是让Base继承自shared_from_this

class Base : public std::shared_from_this<Base>
{
public:
    void addChild(std::shared_ptr<Base>& child)
    {
        ...
    }
}

class Derived : public Base
{}

int main()
{
    Base a;
    std::shared_ptr<Derived> b = std::make_shared<Derived>();
    std::shared_ptr<Base> c = std::make_shared<Base>(b->weak_from_this());
    a.addChild(c);  // OK
}

然后在需要传父类智能指针的地方使用std::make_shared<Base>(b->weak_from_this())将子类智能指针转换成父类智能指针,这样就可以顺利的把b指针保存的对象顺利传入addChild函数了.

当然,如果addChild函数内不需要保存shared_ptr的话,入参直接改成对Base对象的引用才是最好的解决方案.


http://www.kler.cn/a/151939.html

相关文章:

  • 主流数据库类型总结
  • 【Web】攻防世界Web_php_wrong_nginx_config
  • Windows Terminal CMD 终端配置方案: 不只是酷炫外观
  • 论文导读 | 10月专题内容精选:人的预测
  • 论文笔记:详解NEUPSL DSI
  • 【MySQL:从零开始练级】环境安装与基础认识
  • redis运维(二十)redis 的扩展应用 lua(二)
  • Windows系列:windows2003-建立域
  • Python streamlit指南,构建令人惊叹的可视化Web界面!
  • python-元组和列表的异同
  • Linux下将Java项目(Jar包)打包成服务
  • 删除list中除最后一个之外所有的数据
  • 非空断言,
  • 五种多目标优化算法(MSSA、MOAHA、MOPSO、NSGA3、NSGA2)求解微电网多目标优化调度(MATLAB)
  • 交叉熵损失函数(Cross-Entropy Loss Function)
  • 如何在VS2022上的MFC项目中操作Excel(VS2010、VS2012、VS2015、VS2017、VS2019使用方法一样)
  • RabbitMQ之延迟消息
  • Python与设计模式--备忘录模式
  • 三、ts高级笔记,
  • Dynamsoft Barcode Reader教程:如何使用Dynamsoft Java条形码阅读器扫描多个条形码