C++ shared_ptr
shared_ptr共享它指向的对象,多个shared_ptr可以指向(关联)相同的对象,在内部采用计数机制来实现。
当新的shared_ptr与对象关联时,引用计数增加1。
当shared_ptr超出作用域时,引用计数减1。当引用计数变为0时,则表示没有任何shared_ptr与对象关联,则释放该对象。
一、基本用法
shared_ptr的构造函数也是explicit,但是,没有删除拷贝构造函数和赋值函数。
1)初始化
方法一:
shared_ptr p0(new AA(“西施”)); // 分配内存并初始化。
方法二:
shared_ptr p0 = make_shared(“西施”); // C++11标准,效率更高。
shared_ptr pp1=make_shared(); // 数据类型为int。
shared_ptr pp2 = make_shared(); // 数据类型为AA,默认构造函数。
shared_ptr pp3 = make_shared(“西施”); // 数据类型为AA,一个参数的构造函数。
shared_ptr pp4 = make_shared(“西施”,8); // 数据类型为AA,两个参数的构造函数。
方法三:
AA* p = new AA(“西施”);
shared_ptr p0§; // 用已存在的地址初始化。
方法四:
shared_ptr p0(new AA(“西施”));
shared_ptr p1(p0); // 用已存在的shared_ptr初始化,计数加1。
shared_ptr p1=p0; // 用已存在的shared_ptr初始化,计数加1。
2)使用方法
智能指针重载了*和->操作符,可以像使用指针一样使用shared_ptr。
use_count()方法返回引用计数器的值。
unique()方法,如果use_count()为1,返回true,否则返回false。
shared_ptr支持赋值,左值的shared_ptr的计数器将减1,右值shared_ptr的计算器将加1。
get()方法返回裸指针。
不要用同一个裸指针初始化多个shared_ptr。
不要用shared_ptr管理不是new分配的内存。
3)用于函数的参数
与unique_ptr的原理相同。
4)不支持指针的运算(+、-、++、–)
二、更多细节
1)将一个unique_ptr赋给另一个时,如果源unique_ptr是一个临时右值,编译器允许这样做;如果源unique_ptr将存在一段时间,编译器禁止这样做。一般用于函数的返回值。
2)用nullptr给shared_ptr赋值将把计数减1,如果计数为0,将释放对象,空的shared_ptr==nullptr。
3)release()释放对原始指针的控制权,将unique_ptr置为空,返回裸指针。
4)std::move()可以转移对原始指针的控制权。还可以将unique_ptr转移成shared_ptr。
5)reset()改变与资源的关联关系。
pp.reset(); // 解除与资源的关系,资源的引用计数减1。
pp. reset(new AA(“bbb”)); // 解除与资源的关系,资源的引用计数减1。关联新资源。
6)swap()交换两个shared_ptr的控制权。
void swap(shared_ptr &_Right);
7)shared_ptr也可象普通指针那样,当指向一个类继承体系的基类对象时,也具有多态性质,如同使用裸指针管理基类对象和派生类对象那样。
8)shared_ptr不是绝对安全,如果程序中调用exit()退出,全局的shared_ptr可以自动释放,但局部的shared_ptr无法释放。
9)shared_ptr提供了支持数组的具体化版本。
数组版本的shared_ptr,重载了操作符[],操作符[]返回的是引用,可以作为左值使用。
10)shared_ptr的线程安全性:
shared_ptr的引用计数本身是线程安全(引用计数是原子操作)。
多个线程同时读同一个shared_ptr对象是线程安全的。
如果是多个线程对同一个shared_ptr对象进行读和写,则需要加锁。
多线程读写shared_ptr所指向的同一个对象,不管是相同的shared_ptr对象,还是不同的shared_ptr对象,也需要加锁保护。
11)如果unique_ptr能解决问题,就不要用shared_ptr。unique_ptr的效率更高,占用的资源更少。
示例1:
#include <iostream>
#include <memory>
using namespace std;class AA
{
public:string m_name;AA() { cout << m_name << "调用构造函数AA()。\n"; }AA(const string & name) : m_name(name) { cout << "调用构造函数AA("<< m_name << ")。\n"; }~AA() { cout << "调用了析构函数~AA(" << m_name << ")。\n"; }
};int main()
{shared_ptr<AA> pa0(new AA("西施a")); // 初始化资源西施a。shared_ptr<AA> pa1 = pa0; // 用已存在的shared_ptr拷贝构造,计数加1。shared_ptr<AA> pa2 = pa0; // 用已存在的shared_ptr拷贝构造,计数加1。cout << "pa0.use_count()=" << pa0.use_count() << endl; // 值为3。shared_ptr<AA> pb0(new AA("西施b")); // 初始化资源西施b。shared_ptr<AA> pb1 = pb0; // 用已存在的shared_ptr拷贝构造,计数加1。cout << "pb0.use_count()=" << pb0.use_count() << endl; // 值为2。pb1 = pa1; // 资源西施a的引用加1,资源西施b的引用减1。pb0 = pa1; // 资源西施a的引用加1,资源西施b的引用成了0,将被释放。cout << "pa0.use_count()=" << pa0.use_count() << endl; // 值为5。cout << "pb0.use_count()=" << pb0.use_count() << endl; // 值为5。
}
推荐一个零声学院项目课,个人觉得老师讲得不错,分享给大家:
零声白金学习卡(含基础架构/高性能存储/golang云原生/音视频/Linux内核)
https://xxetb.xet.tech/s/3Zqhgt
相关文章:
C++ shared_ptr
shared_ptr共享它指向的对象,多个shared_ptr可以指向(关联)相同的对象,在内部采用计数机制来实现。 当新的shared_ptr与对象关联时,引用计数增加1。 当shared_ptr超出作用域时,引用计数减1。当引用计数变为…...
2024.6.15
2024.6.15 【夜幽幽,月优优,曲悠悠,吾忧忧。】 Saturday 五月初十 <theme oi-“DP”> 看几道DP基础题, 巩固一下DP思路和基础 Coin Combinations I //2024.6.15 //by white_ice //Coin Combinations I CSES - 1635 #i…...
堆栈溢出的攻击 -fno-stack-protector stack smash 检测
在程序返回的一条语句堆栈项目处,用新函数的起始地址覆盖,将会跳转到执行新函数。 现在系统对这个行为做了判断,已经无法实施这类攻击或技巧。 1,测试代码 #include <stdio.h> void cc() {printf("I am cc( )\n"…...
掌握特劳特定位理论核心,明晰企业战略定位之重
在当今瞬息万变的市场环境中,企业战略定位的重要性日益凸显。它不仅是企业在激烈竞争中保持优势的关键,更是企业实现长期可持续发展的基石。 哈佛大学战略学教授迈克尔波特(Michael Porter)指出战略就是形成一套独具的运营活动&a…...
RAGFlow 学习笔记
RAGFlow 学习笔记 0. 引言1. RAGFlow 支持的文档格式2. 嵌入模型选择后不再允许改变3. 干预文件解析4. RAGFlow 与其他 RAG 产品有何不同? 5. RAGFlow 支持哪些语言? 6. 哪些嵌入模型可以本地部署? 7. 为什么RAGFlow解析文档的时间比…...
使用Docker-Java监听Docker容器的信息
使用Docker-Java监听Docker容器的信息 Docker作为一种轻量级的容器化平台,极大地方便了应用的部署与管理。然而,在实际使用过程中,我们常常需要对运行中的容器进行监控,以确保其健康状态,并能及时响应各种异常情况。本…...
Spring Boot + Mybatis Plus实现登录注册
Spring Boot 实现登录注册 1. 注册 业务逻辑 客户端输入注册时需要的用户参数,比如:账户名、密码、确认密码、其他服务端接收到客户端的请求参数进行校验,然后判断是否有误,有误的地方就将错误信息抛出将密码进行加密之后存储到…...
IDEA创建web项目
IDEA创建web项目 第一步:创建一个空项目 第二步:在刚刚创建的项目下创建一个子模块 第三步:在子模块中引入web 创建结果如下: 这里我们需要把这个目录移到main目录下,并改名为webapp,结果如下 将pom文件…...
二手物品交易系统的设计
管理员账户功能包括:系统首页,个人中心,管理员管理,商家管理,用户管理,商品管理,用户咨询管理 商家账户功能包括:系统首页,个人中心,商品管理,用…...
探索大数据在信用评估中的独特价值
随着我国的信用体系越来越完善,信用将影响越来越多的人。现在新兴的大数据信用和传统信用,形成了互补的优势,大数据信用变得越来越重要,那大数据信用风险检测的重要性主要体现在什么地方呢?本文将详细为大家介绍一下,…...
MFC基础学习应用
MFC基础学习应用 1.基于对话框的使用 左上角为菜单键(其下的关于MFC主要功能由IDD_ABOUTBOX决定) 附图 右下角为按钮(基本功能由IDD_DIALOG决定,添加按钮使用由左上角的工具箱完成) 附图 2.自行添加功能与按钮//功能代码 void CMFCApplication4Dlg:…...
Gradle实现类似Maven的profiles功能
版本说明 GraalVM JDK 21.0.3Gradle 8.7Spring Boot 3.2.5 目录结构 指定环境打包 application.yml/yaml/properties 执行 bootJar 打包命令前要先执行 clean【其它和 processResources 相关的命令也要先执行 clean】,否则 active 值不会变! spring…...
【强化学习】gymnasium自定义环境并封装学习笔记
【强化学习】gymnasium自定义环境并封装学习笔记 gym与gymnasium简介gymgymnasium gymnasium的基本使用方法使用gymnasium封装自定义环境官方示例及代码编写环境文件__init__()方法reset()方法step()方法render()方法close()方法 注册环境创建包 Package(最后一步&a…...
TLE9879的基于Arduino调试板SWD刷写接口
官方的Arduino评估板,如下图所示: 如果你有官方的调试器,应该不用关注本文章,如下图连接就是: 如果,您和博主一样需要自己飞线的话,如下图所示:PCB的名称在右边整理,SWD的…...
基于 Delphi 的前后端分离:之五,使用 HTMX 让页面元素组件化之面向对象的Delphi代码封装
前情提要 本博客上一篇文章,描述了使用 Delphi 作为后端的 Web Server,前端使用 HTMX 框架,把一个开源的前端图表 JS 库,进行了组件化。 上一篇文章仅仅是描述了简单的前端代码组件化的可能性,依然是基于前端库的 JS…...
讲透计算机网络知识(实战篇)01——计算机网络和协议
一、计算机网络和协议 1、网络和互联网络 1.1 网络、互联网、Internet 用交换机、集线器连接在一起的计算机构成一个网络。 用路由器连接多个网络,形成互联网。 全球最大的互联网:Internet。 1.2 网络举例 家庭互联网 图中的无线拨号路由器既是路由…...
8个宝藏APP,个个都牛逼哈拉!
AI视频生成:小说文案智能分镜智能识别角色和场景批量Ai绘图自动配音添加音乐一键合成视频https://aitools.jurilu.com/ 目前win7已经逐渐淡出人们的视野,大部分人都开始使用win10,在日常工作和使用中,创客们下载神奇的软件能大幅提…...
使用docker构建java应用
1、docker简介 Docker是一个开源的容器化平台,可以帮助开发人员将应用程序及其依赖项打包成一个可移植的容器。容器化是一种轻量级的虚拟化技术,可以使应用程序在不同的操作系统和环境中具有一致的运行方式。 使用Docker带来的好处包括: 简…...
Oracle 存储过程
Oracle存储过程 创建存储过程 CREATE OR REPLACE PROCEDURE UPDATE_EMPLOYEE_SALARY(p_employee_id IN NUMBER,p_employee_salary IN NUMBER )AS BEGINUPDATE employeesSET salary p_employee_salaryWHERE employee_id p_employee_id;COMMIT;EXCEPTIONWHEN NO_DATA_FOUND T…...
下载站名文件
自学python如何成为大佬(目录):https://blog.csdn.net/weixin_67859959/article/details/139049996?spm1001.2014.3001.5501 得到了请求地址与请求参数后,可以发现请求参数中的出发地与目的地均为车站名的英文缩写。而这个英文缩写的字母是通过输入中文车站名转换…...
rknn优化教程(二)
文章目录 1. 前述2. 三方库的封装2.1 xrepo中的库2.2 xrepo之外的库2.2.1 opencv2.2.2 rknnrt2.2.3 spdlog 3. rknn_engine库 1. 前述 OK,开始写第二篇的内容了。这篇博客主要能写一下: 如何给一些三方库按照xmake方式进行封装,供调用如何按…...
Qt Widget类解析与代码注释
#include "widget.h" #include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->setupUi(this); }Widget::~Widget() {delete ui; }//解释这串代码,写上注释 当然可以!这段代码是 Qt …...
Frozen-Flask :将 Flask 应用“冻结”为静态文件
Frozen-Flask 是一个用于将 Flask 应用“冻结”为静态文件的 Python 扩展。它的核心用途是:将一个 Flask Web 应用生成成纯静态 HTML 文件,从而可以部署到静态网站托管服务上,如 GitHub Pages、Netlify 或任何支持静态文件的网站服务器。 &am…...
数据链路层的主要功能是什么
数据链路层(OSI模型第2层)的核心功能是在相邻网络节点(如交换机、主机)间提供可靠的数据帧传输服务,主要职责包括: 🔑 核心功能详解: 帧封装与解封装 封装: 将网络层下发…...
ServerTrust 并非唯一
NSURLAuthenticationMethodServerTrust 只是 authenticationMethod 的冰山一角 要理解 NSURLAuthenticationMethodServerTrust, 首先要明白它只是 authenticationMethod 的选项之一, 并非唯一 1 先厘清概念 点说明authenticationMethodURLAuthenticationChallenge.protectionS…...
sqlserver 根据指定字符 解析拼接字符串
DECLARE LotNo NVARCHAR(50)A,B,C DECLARE xml XML ( SELECT <x> REPLACE(LotNo, ,, </x><x>) </x> ) DECLARE ErrorCode NVARCHAR(50) -- 提取 XML 中的值 SELECT value x.value(., VARCHAR(MAX))…...
Spring Boot+Neo4j知识图谱实战:3步搭建智能关系网络!
一、引言 在数据驱动的背景下,知识图谱凭借其高效的信息组织能力,正逐步成为各行业应用的关键技术。本文聚焦 Spring Boot与Neo4j图数据库的技术结合,探讨知识图谱开发的实现细节,帮助读者掌握该技术栈在实际项目中的落地方法。 …...
【碎碎念】宝可梦 Mesh GO : 基于MESH网络的口袋妖怪 宝可梦GO游戏自组网系统
目录 游戏说明《宝可梦 Mesh GO》 —— 局域宝可梦探索Pokmon GO 类游戏核心理念应用场景Mesh 特性 宝可梦玩法融合设计游戏构想要素1. 地图探索(基于物理空间 广播范围)2. 野生宝可梦生成与广播3. 对战系统4. 道具与通信5. 延伸玩法 安全性设计 技术选…...
AI书签管理工具开发全记录(十九):嵌入资源处理
1.前言 📝 在上一篇文章中,我们完成了书签的导入导出功能。本篇文章我们研究如何处理嵌入资源,方便后续将资源打包到一个可执行文件中。 2.embed介绍 🎯 Go 1.16 引入了革命性的 embed 包,彻底改变了静态资源管理的…...
基于TurtleBot3在Gazebo地图实现机器人远程控制
1. TurtleBot3环境配置 # 下载TurtleBot3核心包 mkdir -p ~/catkin_ws/src cd ~/catkin_ws/src git clone -b noetic-devel https://github.com/ROBOTIS-GIT/turtlebot3.git git clone -b noetic https://github.com/ROBOTIS-GIT/turtlebot3_msgs.git git clone -b noetic-dev…...
