C++11智能指针std::shared_ptr介绍及使用
介绍
shared_ptr是一种智能指针(smart pointer),作用有如同指针,但会记录有多少个shared_ptrs共同指向一个对象。这便是所谓的引用计数(reference counting),比如我们把只能指针赋值给另外一个对象,那么对象多了一个智能指针指向它,所以这个时候引用计数会增加一个,我们可以用shared_ptr.use_count()函数查看这个智能指针的引用计数。

下面放上c++参考手册的介绍:




具体对应模块参考链接:https://zh.cppreference.com/w/cpp/memory/shared_ptr
示例:
#include <iostream>
#include <memory> //使用shared_ptr需要include它int main() {//通过make_shared创建shared_ptrstd::shared_ptr<int> p1 = std::make_shared<int>();*p1 = 78;std::cout << "p1 = " << *p1 << std::endl;//查看引用计数std::cout << "p1 Reference count = " << p1.use_count() << std::endl;//第二个shared_ptr也将在内部指向相同的指针//这将会使引用计数变为2std::shared_ptr<int> p2(p1);//查看引用计数std::cout << "p2 Reference count = " << p2.use_count() << std::endl;std::cout << "p1 Reference count = " << p1.use_count() << std::endl;//比较智能指针if (p1 == p2) {std::cout << "p1 and p2 are pointing to same pointer\n";}std::cout << "Reset p1" << std::endl;//重置shared_ptr,在这种情况下,其内部不会指向内部的任何指针//因此其引用计数将会变为0p1.reset();std::cout << "p1 Reference Count = " << p1.use_count() << std::endl;//重置shared_ptr,在这种情况下,其内部将会指向一个新的指针//因此其引用计数将会变为1p1.reset(new int(11));std::cout << "p1 Reference Count = " << p1.use_count() << std::endl;//分配nullptr将取消关联指针并使其指向空值p1 = nullptr; std::cout << "p1 Reference Count = " << p1.use_count() << std::endl;if (!p1) {std::cout << "p1 is NULL" << std::endl;}return 0;
}
输出:
p1 = 78
p1 Reference count = 1
p2 Reference count = 2
p1 Reference count = 2
p1 and p2 are pointing to same pointer
Reset p1
p1 Reference Count = 0
p1 Reference Count = 1
p1 Reference Count = 0
p1 is NULL
下面讨论下怎样使用 std::shared_ptr自定义Deleter.
当一个shared_ptr对象超出作用域时,其析构函数被调用,在析构函数中,将其引用计数减1,如果引用计数的值变为0,则删除关联的原始指针。
要删除析构函数中的内部原始指针,默认情况下,shared_ptr调用delete()函数,即
delete Pointer;
但是,我们在析构函数中并不总是要使用delete函数,还可能有其他的需求。
如果shared_ptr指向一个数组而不是一个简单的指针
std::shared_ptr<int> p3(new int[12]);
在其析构函数中,shared_ptr将会调用 delete函数来删除int数组,而正确的方式是使用 delete []
增加定制deleter到shared_ptr
在这种情况下,我们可以将一个回调传递给shared_ptr的构造函数,该构造函数将会在其析构函数中被调用
定制Deleter作为函数指针
//函数调用接收到的指针上的delete[]
void deleter(Sample *x){std::cout<<"DELETE FUNCTION CALLED\n";delete[] x;
}
在shared_ptr的构造函数中传递函数指针,以提供自定义的deleter
//使用定制deleter创建sharedptr
std::shared_ptr<Sample> p3(new Sample[12], deleter);
完整的例子如下:
#include <iostream>
#include <memory>struct Sample {Sample() {std::cout << "CONSTRUCTOR\n";}~Sample() {std::cout << "DESTRUCTOR\n";}
};//在接收到的指针上调用delte[]的函数
void deleter(Sample* x) {std::cout << "DELETER FUNCTION CALLED\n";delete[] x;
}int main() {//使用定制的deleter创建shared_ptrstd::shared_ptr<Sample> p3(new Sample[12], deleter);return 0;
}
输出:
CONSTRUCTOR
CONSTRUCTOR
CONSTRUCTOR
CONSTRUCTOR
CONSTRUCTOR
CONSTRUCTOR
CONSTRUCTOR
CONSTRUCTOR
CONSTRUCTOR
CONSTRUCTOR
CONSTRUCTOR
CONSTRUCTOR
DELETER FUNCTION CALLED
DESTRUCTOR
DESTRUCTOR
DESTRUCTOR
DESTRUCTOR
DESTRUCTOR
DESTRUCTOR
DESTRUCTOR
DESTRUCTOR
DESTRUCTOR
DESTRUCTOR
DESTRUCTOR
DESTRUCTOR
相关文章:
C++11智能指针std::shared_ptr介绍及使用
介绍 shared_ptr是一种智能指针(smart pointer),作用有如同指针,但会记录有多少个shared_ptrs共同指向一个对象。这便是所谓的引用计数(reference counting),比如我们把只能指针赋值给另外一个对象,那么对象多了一个智能指针指向它,所以这个时候引用计数…...
华为OD机试 - 数字的排列(Python) | 机试题+算法思路+考点+代码解析 【2023】
数字的排列 题目 小华是个很有对数字很敏感的小朋友, 他觉得数字的不同排列方式有特殊的美感。 某天,小华突发奇想,如果数字多行排列, 第一行1个数, 第二行2个, 第三行3个, 即第n行n个数字,并且奇数行正序排列, 偶数行逆序排列,数字依次累加。 这样排列的数字一定很…...
Android 事件分发机制(4)-常见面试题
目录 1.你了解过Android的事件分发机制吗?请大致介绍一下 2、如果父view中不拦截down事件,拦截move,up事件,在子view中设置了requestDisallowInterceptTouchEvent(true);(请求父view不拦截事件)这个标志后,…...
计算机四级 [操作系统] | 选择题 2 重点标注版
1.某一个单道批处理系统几乎同时依次到达4个作业,这4个作业的预计运行时间分别为8、4、4和4分钟,按照短作业优先的调度算法运行,请问该批作业的平均周转时间为多少 B A. 14分钟 B. 11分钟 C. 20分钟 D. 10分钟 2.下列与进程具有一一对应的关…...
想玩好ChatGPT?不妨看看这篇文章
相信点进来的铁汁,此时已经对 ChatGPT 有所了解,并想上手体验一番 首先大伙儿要注意,不要被骗了。 现在很多商家提供的 ChatGPT 服务,不仅价格奇高,而且据我所知,有些压根不是 ChatGPT 。 想玩最好去官网注册,具体方法大伙自个儿查一查嗷。 怎么用好 ChatGPT 虽然 …...
day31 IO流
文章目录回顾collectionArrayTestListHashSetTsetHashMapTestPropertiesTreeSetTestIO流FileInputStreamTest01 文件流初步FileInputStreamTest02 循环读FileStreamTest03FileInputStreamTes04 需要掌握FiLeInputStreamTest5FileOutputStreamTest01Copy1 文件拷贝FileReaderTes…...
Linux 防火墙配置(iptables和firewalld)
目录 防火墙基本概念 Iptables讲解 Iptables表 Iptables规则链 Iptables控制类型 Iptables命令配置 firewalld讲解 Firewalld区域概念 Firewalld两种配置方法 firewall-cmd命令行基础配置 firewall-config图形化配置 防火墙基本概念 防火墙就是根据系统管理员设定的…...
深度学习基础(一)
记得17年第一次阅读深度学习相关文献及代码觉得不是很顺畅,做客户端开发时间久了,思维惯性往往觉得比较迷茫。 而且文章中涉及的数学公式及各种符号又觉得很迷惑,虽然文章读下来了,代码也调试过了,意识里并没有轻松的…...
Maven 常用命令
mvn archetype: create :创建Maven 项目mvn compile :编译源代码。mvn deploy:发布项目。mvn test-compile :编译测试源代码mvn test:运行应用程序中的单元测试mvn site:生成项目相关信息的网站mvn clean:清除项目目录中的生成结果mvn package:根据项目生成的iar/war等mvn inst…...
2023年100道最新Android面试题,常见面试题及答案汇总
除了需要掌握牢固的专业技术之外,还需要刷更多的面试去在众多的面试者中杀出重围。小编特意整理了100道Android面试题,送给大家,希望大家都能顺利通过面试,拿下高薪。赶紧拿去吧~~文末有答案Q1.组件化和arouter原理Q2.自定义view&…...
[JavaEE系列] 详解面试中HTTP协议HTTPS协议
文章目录HTTP不安全HTTPS中的加密算法对称加密非对称加密混合加密HTTPS中的摘要算法HTTPS中的数字证书SSL /TLS握手TCP建立连接(三次握手)三次握手中常见的面试题:TCP断开连接(四次挥手)四次挥手中常见的面试题&#x…...
mac 好用的类似Xshell工具
下载royal TSX 5.1.1 http://share.uleshi.com/f/9490615-685692355-33bf1e修改mac的etc/hosts文件权限访达(鼠标右键) -> 前往文件夹 ->输入/private --> 打开etc/hosts --> 显示简洁(鼠标右键) --> 权限改成读和写hosts文件写入如下内容:# Royal T…...
浅谈SQL中的union和union all
文章目录概念基础语法使用技巧区别总结概念 MySQL UNION 操作符用于连接两个以上的 SELECT 语句的结果组合到一个结果集合中。多个 SELECT 语句会删除重复的数据。 UNION 操作符选取不同的值,如果允许得到重复的值,可以使用 UNION ALL 基础语法 -- u…...
P6软件应用的核心收益
卷首语 提供了多用户、多项目的功能模块,支持多层次项目等级划分,资源分配计划,记录实际数据,自定义视图,并具有用户定义字段的扩展功能。 利用最佳实践,建立企业模板库 P6软件支持用户使用模板编制项目…...
性能测试中,我遇到的8个常见问题总结
性能压测中我们需要明白以下几点: 1、好的开始是成功的一半,前期的准备非常重要; 2、过程中,关注每个细节,多个维度监控; 3、在调优中多积累经验; 4、对结果负责,测试报告要清晰…...
kafka架构体系
Kafka简介 Kafka是一个由Scala和Java编写的企业级的消息发布和订阅系统,最早是由Linkedin公司开发,最终开源到Apache软件基金会的项目。Kafka是一个分布式的,支持分区的,多副本的和多订阅者的高吞吐量的消息系统,被广…...
【Kafka】三.Kafka怎么保证高可用 学习总结
Kafka 的副本机制 Kafka 的高可用实现主要依赖副本机制。 Broker 和 Partition 的关系 在分析副本机制之前,先来看一下 Broker 和 Partition 之间的关系。Broker 在英文中是代理、经纪人的意思,对应到 Kafka 集群中,是一个 Kafka 服务器节…...
Python学习笔记7:再谈抽象
再谈抽象 对象 多态 即便你不知道变量指向的是哪种对象,也能够对其执行操作封装 向外部隐藏不必要的细节。继承 类 class Person: def set_name(self, name): self.name name def get_name(self): return self.name def greet(self): print("Hello, world…...
钣金行业mes解决方案,缩短产品在制周期
钣金加工行业具有多品种、小批量离散制造行业的典型特点。一些常见的下料车间、备料车间、冲压车间、冲剪生产线等。一般来说,核心业务是钣金加工的生产单位。 一般来说,与大规模生产相比,这种生产方式效率低、成本高,自动化难度…...
【Linux】——git和gdb的简单使用技巧
目录 1.\r&&\n 2.缓冲区 3.做一个Linux的小程序——进度条 1.makefile代码: 2.proc.h代码 3.proc.c代码 4.main.c代码 4.git(上传做好的小程序) 5.Linux调试器-gdb使用 1.\r&&\n 在Linux中,可以将\r看成…...
R语言AI模型部署方案:精准离线运行详解
R语言AI模型部署方案:精准离线运行详解 一、项目概述 本文将构建一个完整的R语言AI部署解决方案,实现鸢尾花分类模型的训练、保存、离线部署和预测功能。核心特点: 100%离线运行能力自包含环境依赖生产级错误处理跨平台兼容性模型版本管理# 文件结构说明 Iris_AI_Deployme…...
Objective-C常用命名规范总结
【OC】常用命名规范总结 文章目录 【OC】常用命名规范总结1.类名(Class Name)2.协议名(Protocol Name)3.方法名(Method Name)4.属性名(Property Name)5.局部变量/实例变量(Local / Instance Variables&…...
【解密LSTM、GRU如何解决传统RNN梯度消失问题】
解密LSTM与GRU:如何让RNN变得更聪明? 在深度学习的世界里,循环神经网络(RNN)以其卓越的序列数据处理能力广泛应用于自然语言处理、时间序列预测等领域。然而,传统RNN存在的一个严重问题——梯度消失&#…...
【Go】3、Go语言进阶与依赖管理
前言 本系列文章参考自稀土掘金上的 【字节内部课】公开课,做自我学习总结整理。 Go语言并发编程 Go语言原生支持并发编程,它的核心机制是 Goroutine 协程、Channel 通道,并基于CSP(Communicating Sequential Processes࿰…...
面向无人机海岸带生态系统监测的语义分割基准数据集
描述:海岸带生态系统的监测是维护生态平衡和可持续发展的重要任务。语义分割技术在遥感影像中的应用为海岸带生态系统的精准监测提供了有效手段。然而,目前该领域仍面临一个挑战,即缺乏公开的专门面向海岸带生态系统的语义分割基准数据集。受…...
C++课设:简易日历程序(支持传统节假日 + 二十四节气 + 个人纪念日管理)
名人说:路漫漫其修远兮,吾将上下而求索。—— 屈原《离骚》 创作者:Code_流苏(CSDN)(一个喜欢古诗词和编程的Coder😊) 专栏介绍:《编程项目实战》 目录 一、为什么要开发一个日历程序?1. 深入理解时间算法2. 练习面向对象设计3. 学习数据结构应用二、核心算法深度解析…...
Git 3天2K星标:Datawhale 的 Happy-LLM 项目介绍(附教程)
引言 在人工智能飞速发展的今天,大语言模型(Large Language Models, LLMs)已成为技术领域的焦点。从智能写作到代码生成,LLM 的应用场景不断扩展,深刻改变了我们的工作和生活方式。然而,理解这些模型的内部…...
计算机基础知识解析:从应用到架构的全面拆解
目录 前言 1、 计算机的应用领域:无处不在的数字助手 2、 计算机的进化史:从算盘到量子计算 3、计算机的分类:不止 “台式机和笔记本” 4、计算机的组件:硬件与软件的协同 4.1 硬件:五大核心部件 4.2 软件&#…...
SpringAI实战:ChatModel智能对话全解
一、引言:Spring AI 与 Chat Model 的核心价值 🚀 在 Java 生态中集成大模型能力,Spring AI 提供了高效的解决方案 🤖。其中 Chat Model 作为核心交互组件,通过标准化接口简化了与大语言模型(LLM࿰…...
算法打卡第18天
从中序与后序遍历序列构造二叉树 (力扣106题) 给定两个整数数组 inorder 和 postorder ,其中 inorder 是二叉树的中序遍历, postorder 是同一棵树的后序遍历,请你构造并返回这颗 二叉树 。 示例 1: 输入:inorder [9,3,15,20,7…...
