c++智能指针shared_ptr

文章目录

  • 概念
    • 1.shared_ptr
      • 1.基本使用
      • 2.如何获取原始指针
      • 3. 指定删除器
    • 2 使用shared_ptr要注意的问题
      • 2.1不要用一个原始指针初始化多个shared_ptr
      • 2.2. 避免循环引用
  • 小结

概念

C++程序设计中使用堆内存是非常频繁的操作,堆内存的申请和释放都由程序员自己管理。内存管理是非常麻烦的,C++11中引入了智能指针的概念,方便管理堆内存。使用普通指针,容易造成堆内存泄露(忘记释放),二次释放,程序发生异常时内存泄露等问题等,使用智能指针能更好的管理堆内存。

智能指针主要包含shared_ptr,unique_ptr,weak_ptr。今天先看看shared_ptr吧。

1.shared_ptr

如下图:
shared_ptr
shared_ptr主要包含2个部分,raw_ptr和share_count_object。看下代码示例:
shared_ptr
ptr_base
如上图,shared_ptr2个指针都在基类中,ptr就是在堆上创建的裸指针对象,另外一个是计数。

1.基本使用

	std::shared_ptr<A> pa(new A());std::cout << "pa.use_count() = " << pa.use_count() << std::endl;std::shared_ptr<A> pb = std::make_shared<A>();std::cout << "pb.use_count() = " << pb.use_count() << std::endl;

2.如何获取原始指针

class B : std::enable_shared_from_this<B>
{
public:virtual ~B(){cout << "delete B\n" << endl;}
};std::shared_ptr<B> pa = std::make_shared<B>();
B* pb = pa.get(); //获取原始指针。

3. 指定删除器

void DeleteIntPtr(int *p) {cout << "call DeleteIntPtr" << endl;delete p;
}//使用
std::shared_ptr<int> p(new int(1), DeleteIntPtr);
std::shared_ptr<int> p2(new int(1), [](int *p) {cout << "call lambda1 delete p" << endl;delete p;
});
std::shared_ptr<int> p3(new int[10], [](int *p) {cout << "call lambda2 delete p" << endl;delete [] p; // 数组删除
});

当p的引用计数为0时,自动调用删除器DeleteIntPtr来释放对象的内存。

2 使用shared_ptr要注意的问题

2.1不要用一个原始指针初始化多个shared_ptr

{int *ptr = new int;shared_ptr<int> p1(ptr);shared_ptr<int> p2(ptr); // 逻辑错误
}

2.2. 避免循环引用

class A {
public:std::shared_ptr<B> bptr;~A() {cout << "A is deleted" << endl;}
};
class B {
public:std::shared_ptr<A> aptr;~B() {cout << "B is deleted" << endl;}
};

使用如下:

{std::shared_ptr<A> ap(new A);std::shared_ptr<B> bp(new B);ap->bptr = bp;bp->aptr = ap;
}

这就是循环引用,要防止出现这种情况,会出现指针释放不掉的。

小结

看完这篇,差不多了,对c++的智能指针有了一定的了解,特别是shared_ptr的各种情况。有兴趣,可以来学习学习。当然,还要注意多看一些官网文档。OK,这篇结束。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/362819.html

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

相关文章

安装 Docker 环境(通过云平台创建一个实例实现)

目录 1. 删除原有 yum 2. 手动配置 yum 源 3. 删除防火墙规则 4. 保存防火墙配置 5. 修改系统内核。打开内核转发功能。 6. 安装 Docker 7. 设置本地镜像仓库 8.重启服务 1. 删除原有 yum rm -rfv /etc/yum.repos.d/* 2. 手动配置 yum 源 使用 centos7-1511.iso 和 Xi…

Python 语法基础二

7.常用内置函数 执行这个命令可以查看所有内置函数和内置对象&#xff08;两个下划线&#xff09; >>>dir(__builtins__) [__class__, __contains__, __delattr__, __delitem__, __dir__, __doc__, __eq__, __format__, __ge__, __getattribute__, __getitem__, __gt…

深入剖析 Android 网络开源库 Retrofit 的源码详解

文章目录 概述一、Retrofit 简介Android主流网络请求库 二、Retrofit 源码剖析1. Retrofit 网络请求过程2. Retrofit 实例构建2.1 Retrofit.java2.2 Retrofit.Builder()2.2.1 Platform.get()2.2.2 Android 平台 2.3 Retrofit.Builder().baseUrl()2.4 Retrofit.Builder.client()…

OpenAI穿着「皇帝的新衣」;扒了数万条帖子汇总100种AIGC玩法;北美出海的财务避坑指南;我创业「如」有CTO | ShowMeAI日报

&#x1f440;日报&周刊合集 | &#x1f3a1;生产力工具与行业应用大全 | &#x1f9e1; 点赞关注评论拜托啦&#xff01; 1. 我扒了 Reddit 论坛数万条帖子&#xff0c;汇总了 GenAI 的 100 种玩法 ChatGPT 已经问世一年半了。这期间诞生了很多大语言模型和生成式人工智能…

备份和还原

stai和dnta snat&#xff1a;源地址转换 内网---外网 内网ip转换成可以访问外网的ip 内网的多个主机可以使用一个有效的公网ip地址访问外部网络 DNAT&#xff1a;目的地址转发 外部用户&#xff0c;可以通过一个公网地址访问服务内部的私网服务。 私网的ip和公网ip做一个…

【JavaEE进阶】Spring AOP使用篇

目录 1.AOP概述 2.SpringAOP快速入门 2.1 引入AOP依赖 2.2 编写AOP程序 3. Spring AOP详解 3.1 Spring AOP 核心概念 3.1.1切点(Pointcut) 3.1.2 连接点 (Join Point) 3.1.3 通知(Advice) 3.1.4 切面(Aspect) 3.2 通知类型 3.3PointCut 3.4 切面优先级 3.5 切点表…

「51媒体」政企活动媒体宣发如何做?

传媒如春雨&#xff0c;润物细无声&#xff0c;大家好&#xff0c;我是51媒体网胡老师。 媒体宣传加速季&#xff0c;100万补贴享不停&#xff0c;一手媒体资源&#xff0c;全国100城线下落地执行。详情请联系胡老师。 政企活动媒体宣发是一个系统性的过程&#xff0c;需要明确…

使用Scala爬取安居客房产信息并存入CSV文件

使用Scala爬取安居客房产信息并存入CSV文件 本篇博客中&#xff0c;我们将介绍如何使用Scala语言编写一个简单的程序&#xff0c;来爬取安居客&#xff08;Anjuke&#xff09;网站上的房产信息&#xff0c;并将这些信息存储到CSV文件中。这个示例将涵盖HTTP请求、HTML解析、数…

麒麟系统安装MySQL

搞了一整天&#xff0c;终于搞定了&#xff0c;记录一下。 一、背景 项目的原因&#xff0c;基于JeecgBoot开发的系统需要国产化支持&#xff0c;这就需要在电脑上安装MySQL等支撑软件。 国产化项目的操作系统多是麒麟系统&#xff0c;我的系统如下&#xff1a; arm64架构。…

详细分析Oracle修改默认的时间格式(四种方式)

目录 前言1. 会话级别2. 系统级别3. 环境配置4. 函数格式化5. 总结 前言 默认的日期和时间格式由参数NLS_DATE_FORMAT控制 如果需要修改默认的时间格式&#xff0c;可以通过修改会话级别或系统级别的参数来实现 1. 会话级别 在当前会话中设置日期格式&#xff0c;这只会影响…

CCSP自考攻略+经验总结

备考攻略 备考攻略准备阶段通读阶段精度阶段总复习阶段刷题阶段命运审判 写到最后 备考攻略 趁着对ssp知识点的理解还在&#xff0c;开始ccsp的考证之路&#xff0c;文章结构还是按照cissp备考篇的结构梳理。本次备考和cissp的离职在家备考不同&#xff0c;ccsp是在职利用非工…

2018年全国大学生数学建模竞赛A题高温服装设计(含word论文和源代码资源)

文章目录 一、部分题目二、部分论文三、部分Matlab源代码问题11 求解h1h22 已知h1h2求解温度分布 问题21 求解第二层最佳厚度 四、完整word版论文和源代码&#xff08;两种获取方式&#xff09; 一、部分题目 2018 年高教社杯全国大学生数学建模竞赛题目 A 题 高温作业专用服…

【C语言】字符/字符串+内存函数

目录 Ⅰ、字符函数和字符串函数 1 .strlen 2.strcpy 3.strcat 4.strcmp 5.strncpy 6.strncat 7.strncmp 8.strstr 9.strtok 10.strerror 11.字符函数 12. 字符转换函数 Ⅱ、内存函数 1 .memcpy 2.memmove 3.memcmp 4.memset Ⅰ、字符函数和字符串函数 1 .strlen 函数原型&…

Vite: 关于Rollup打包

概述 Rollup 是一款基于 ES Module 模块规范实现的 JavaScript 打包工具&#xff0c;在前端社区中赫赫有名&#xff0c;同时也在 Vite 的架构体系中发挥着重要作用不仅是 Vite 生产环境下的打包工具&#xff0c;其插件机制也被 Vite 所兼容&#xff0c;可以说是 Vite 的构建基…

JavaScript--js基础(详细 全面)

目录 前言: JavaScript 是什么&#xff1f;JavaScript 简介 1.JavaScript历史 2.JavaScript 具有以下特点 第一个JavaScript程序 1.在脚本文件中编写JavaScript代码 2.JavaScript代码执行顺序 基本语法 1.变量 2.数据类型 3.算术运算符 4.赋值运算 5.字符串运算符 6…

微服务应用与开发知识点练习【Gateway,OpenFeign,Dubbo,RocketMQ和RabbitMQ,JPA,Redis,Mycat】

一、选择题 【Gateway】 1.Spring Cloud Gateway与Nacos整合实现负载均衡时&#xff0c;路由配置中的URI前缀应该是&#xff1f;&#xff08;A &#xff09; A. lb:// B. nacos:// C. http:// D. discovery:// Spring Cloud Gateway与Nacos整合实现负载均衡时&#xff0c…

华为od 2024 | 什么是华为od,od 薪资待遇,od机试题清单

目录 专栏导读华为OD机试算法题太多了&#xff0c;知识点繁杂&#xff0c;如何刷题更有效率呢&#xff1f; 一、逻辑分析二、数据结构1、线性表① 数组② 双指针 2、map与list3、队列4、链表5、栈6、滑动窗口7、二叉树8、并查集9、矩阵 三、算法1、基础算法① 贪心思维② 二分查…

鸿蒙面试心得

自疫情过后&#xff0c;java和web前端都进入了冰河时代。年龄、薪资、学历都成了找工作路上躲不开的门槛。 年龄太大pass 薪资要高了pass 学历大专pass 好多好多pass 找工作的路上明明阳关普照&#xff0c;却有一种凄凄惨惨戚戚说不清道不明的“优雅”意境。 如何破局&am…

vite-ts-cesium项目集成mars3d修改相关的包和配置参考

如果vite技术栈下使用原生cesium&#xff0c;请参考下面文件的包和配置修改&#xff0c;想用原生创建的viewer结合我们mars3d的功能的话。 1. package.json文件 "dependencies": {"cesium": "^1.103.0","mars3d": "^3.7.18&quo…

Java——IO流(一)-(8/8):释放资源-try-catch-finally、try-catch-resource

目录 try-catch-finally 介绍 实例演示1 实例演示2 try-catch-resource 介绍 实例演示 try-catch-finally 介绍 普通的释放流的方法可能会因中间的异常或是其他原因&#xff0c;导致程序执行不到释放流的代码就结束了&#xff0c;会有资源浪费的风险&#xff0c;所以建…