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 classa.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.mzph.cn/news/186182.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Response(Http协议连载)

Response对象 功能&#xff1a; 设置响应消息 设置响应行 格式&#xff1a;HTTP/1.1 200 ok 设置状态码&#xff1a;setStatus(int sc) 设置响应头 设置头&#xff1a;setHeader(String name,String value); 设置响应体 使用步骤&#xff1a; 获取输出流 字符输出流&#xff…

[UGUI]实现从一个道具栏拖拽一个UI道具到另一个道具栏

在Unity游戏开发中&#xff0c;实现UI道具的拖拽功能是一项常见的需求。本文将详细介绍如何使用Unity的UGUI系统和事件系统&#xff0c;实现从一个道具栏拖拽一个UI道具到另一个道具栏的功能。 一、准备工作 首先&#xff0c;你需要在Unity中创建两个道具栏和一些UI道具。道具…

事件机制?

事件流&#xff1a; 描述的页面接收事件的顺序。先进行事件捕获 到达目标元素 在进行事件冒泡 分为事件捕获和事件冒泡 事件冒泡&#xff1a;从具体元素从内向外依次触发事件 从下面这个小案例可以清楚了解什么是事件冒泡 <!DOCTYPE html> <html lang"en"…

C++ -- 每日选择题 -- Day2

第一题 1. 下面代码中sizeof(A)结果为&#xff08;&#xff09; #pragma pack(2) class A {int i;union U{char str[13];int i;}u;void func() {};typedef char* cp;enum{red,green,blue}color; }; A&#xff1a;20 B&#xff1a;21 C&#xff1a;22 D&#xff1a;24 答案及解析…

leecode 回文数

给你一个整数 x &#xff0c;如果 x 是一个回文整数&#xff0c;返回 true &#xff1b;否则&#xff0c;返回 false 。 回文数是指正序&#xff08;从左向右&#xff09;和倒序&#xff08;从右向左&#xff09;读都是一样的整数。 例如&#xff0c;121 是回文&#xff0c;而…

Linux 挂载文件系统为可读写 mount -uw / 和 mount -o remount,rw /

Linux 挂载文件系统为可读写 mount -uw / 和 mount -o remount,rw / 在挂载文件系统为可读写时&#xff0c;我发现一个问题&#xff0c;有时用mount -uw /就可以把文件系统挂载成可写的状态。但有时就会发生 “read-only file system” 的错误&#xff0c;这时我用mount -o re…

智能优化算法应用:基于纵横交叉算法无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用&#xff1a;基于纵横交叉算法无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用&#xff1a;基于纵横交叉算法无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.纵横交叉算法4.实验参数设定5.算法结果6.参考…

【字符串探秘:手工雕刻的String类模拟实现大揭秘】

【本节目标】 1. string类的模拟实现 2.C基本类型互转string类型 3.编码表 &#xff1a;值 --- 符号对应的表 4.扩展阅读 1. string类的模拟实现 1.1 经典的string类问题 上面已经对string类进行了简单的介绍&#xff0c;大家只要能够正常使用即可。在面试中&#xff0c;…

1.网络编程基础知识 - 基础概念、TCP网络通信、UDP网络通信

网络编程 文章目录 网络编程一、概念1.1 网络1.2 IP地址1.2.1 IPv4 介绍1.2.2 IPv6 介绍1.2.3 查看IP地址 1.3 域名和端口1.4 网络协议1.5 TCP与UDP1.6 InetAddress类1.7 Socket 二、TCP网络通信编程2.1 介绍2.2 案例2.2.1 字节流编程案例12.2.2 字节流编程案例22.2.3 字符流编…

【UGUI】Unity教程:实现物品的拖拽功能

大家好&#xff0c;今天&#xff0c;我们将一起学习如何在Unity中实现物品的拖拽功能。这是一个非常实用的技能&#xff0c;无论你是在制作RPG游戏的背包系统&#xff0c;还是在制作策略游戏的建筑放置功能&#xff0c;都会用到这个技能。那么&#xff0c;让我们开始吧&#xf…

5. 文件属性和目录

5. 文件属性和目录 1. Linux 系统的文件类型1.1 普通文件1.2 目录文件1.3 字符设备文件和块设备文件1.4 符号链接文件1.5 管道文件1.6 套接字文件 2. stat 系统调用2.1 struct stat 结构体2.2 st_mode 变量2.3 struct timespec 结构体 3. fstat 和 lstat 函数3.1 fstat 函数3.2…

python中的序列

文章目录 序列类型标准类型运算符标准类型运算符序列类型运算符字符串 序列类型 字符串 列表 元组 由元组构成的列表 标准类型运算符 &#xff08;1&#xff09;按字符串大小比较 标准类型运算符 序列类型运算符 序列类型转换内建函数 注&#xff1a; &#xff08;1&#xff…

深入理解MySQL索引底层数据结构与算法

索引的本质 索引是帮助MySQL高效获取数据的排好序的数据结构 索引的数据结构 二叉树红黑数Hash表B-Tree MySQL索引底层为啥不用二叉树 如图&#xff0c;对单边增长的数据&#xff0c;索引效率没有什么提升 MySQL索引底层为啥不用红黑数 红黑数&#xff1a;二叉平衡树 随…

并发与数据一致性:事务的保障

关注公众号【爱发白日梦的后端】分享技术干货、读书笔记、开源项目、实战经验、高效开发工具等&#xff0c;您的关注将是我的更新动力&#xff01; 并发 并发是计算机系统中同时执行多个独立任务的能力。通过共享资源和并发执行&#xff0c;系统可以提高性能和效率。然而&…

【C 语言经典100例】C 练习实例29

题目&#xff1a;给一个不多于5位的正整数&#xff0c;要求&#xff1a;一、求它是几位数&#xff0c;二、逆序打印出各位数字。 程序分析&#xff1a;学会分解出每一位数&#xff0c;如下解释。 #include <stdio.h>int main( ) {long a,b,c,d,e,x;printf("请输入…

silero-vad 官方新增了java 的demo

原来参考android GitHub - gkonovalov/android-vad: Android Voice Activity Detection (VAD) library. Supports WebRTC VAD GMM, Silero VAD DNN, Yamnet VAD DNN models.的kt改写java demo 可费劲了 上个月 https://github.com/snakers4/silero-vad/tree/master/examples…

MSSQL注入的入门讲解及示例

MSSQL注入是一种常见的网络攻击手段&#xff0c;主要是通过在输入框中插入恶意的SQL代码&#xff0c;使得MSSQL注入是一种常见的网络攻击手段&#xff0c;主要是通过在输入框中插入恶意的SQL代码&#xff0c;使得原本的SQL查询语句被篡改&#xff0c;从而达到攻击者的目的。下面…

计算虚拟化之内存

有了虚拟机&#xff0c;内存就变成了四类&#xff1a; 虚拟机里面的虚拟内存&#xff08;Guest OS Virtual Memory&#xff0c;GVA&#xff09;&#xff0c;这是虚拟机里面的进程看到的内存空间&#xff1b;虚拟机里面的物理内存&#xff08;Guest OS Physical Memory&#xf…

STM32CubeIDE(CUBE-MX hal库)----定时器

系列文章目录 STM32CubeIDE(CUBE-MX hal库)----初尝点亮小灯 STM32CubeIDE(CUBE-MX hal库)----按键控制 STM32CubeIDE(CUBE-MX hal库)----串口通信 文章目录 系列文章目录前言一、定时器二、使用步骤三、HAL库实验代码三、标准库代码 前言 STM32定时器是一种多功能外设&#…

[iOS开发]UITableView的性能优化

一些基础的优化 &#xff08;一&#xff09;CPU 1. 用轻量级对象 比如用不到事件处理的地方&#xff0c;可以考虑使用 CALayer 取代 UIView CALayer * imageLayer [CALayer layer]; imageLayer.bounds CGRectMake(0,0,200,100); imageLayer.position CGPointMake(200,200…