memory动态内存管理学习之shared_ptr

news2024/11/28 6:48:45

此头文件是动态内存管理库的一部分。std::shared_ptr 是一种通过指针保持对象共享所有权的智能指针。多个 shared_ptr 对象可持有同一对象。下列情况之一出现时销毁对象并解分配其内存:

  • 最后剩下的持有对象的 shared_ptr 被销毁;
  • 最后剩下的持有对象的 shared_ptr 被通过 operator= 或 reset() 赋值为另一指针。

成员函数

(构造函数)

构造新的 shared_ptr
(公开成员函数)

(析构函数)

如果没有更多 shared_ptr 指向所持有的对象,则析构该对象
(公开成员函数)

operator=

shared_ptr 赋值
(公开成员函数)
修改器

reset

替换所管理的对象
(公开成员函数)

swap

交换所管理的对象
(公开成员函数)
观察器

get

返回存储的指针
(公开成员函数)

operator*operator->

解引用存储的指针
(公开成员函数)

operator[]

(C++17)

提供到所存储数组的索引访问
(公开成员函数)

use_count

返回 shared_ptr 所指对象的引用计数
(公开成员函数)

unique

(C++20 前)

检查所管理对象是否仅由当前 shared_ptr 的对象管理
(公开成员函数)

operator bool

检查是否有关联的管理对象
(公开成员函数)

owner_before

提供基于持有者的共享指针排序
(公开成员函数)

示例代码

#include <iostream>
#include <memory>

struct C2 { int* data; };
struct C3 { int a; int b; };

int main()
{
	// shared_ptr constructor example
	std::shared_ptr<int> p1;
	std::shared_ptr<int> p2(nullptr);
	std::shared_ptr<int> p3(new int);
	std::shared_ptr<int> p4(new int, std::default_delete<int>());
	std::shared_ptr<int> p5(new int, [](int* p) {delete p; }, std::allocator<int>());
	std::shared_ptr<int> p6(p5);
	std::shared_ptr<int> p7(std::move(p6));
	std::shared_ptr<int> p8(std::unique_ptr<int>(new int));
	std::shared_ptr<C2> obj(new C2);
	std::shared_ptr<int> p9(obj, obj->data);

	std::cout << "use_count:\n";
	std::cout << "p1: " << p1.use_count() << '\t';
	std::cout << "p2: " << p2.use_count() << '\t';
	std::cout << "p3: " << p3.use_count() << '\t';
	std::cout << "p4: " << p4.use_count() << '\t';
	std::cout << "p5: " << p5.use_count() << '\n';
	std::cout << "p6: " << p6.use_count() << '\t';
	std::cout << "p7: " << p7.use_count() << '\t';
	std::cout << "p8: " << p8.use_count() << '\t';
	std::cout << "p9: " << p9.use_count() << '\n';

	// shared_ptr destructor example
	auto deleter = [](int *p) {
		std::cout << "[delete called]\n"; delete p;
	};
	std::shared_ptr<int> foo(new int, deleter);
	std::cout << "use_count:" << foo.use_count() << '\n';
	// shared_ptr::operator= example
	std::shared_ptr<int> foo2;
	std::shared_ptr<int> bar2(new int(10));
	foo2 = bar2;						//copy
	bar2 = std::make_shared<int>(20);	//move
	std::unique_ptr<int> unique(new int(30));
	foo2 = std::move(unique); //move from unique_ptr
	std::cout << "*foo2:" << *foo2 << '\t';
	std::cout << "*bar2:" << *bar2 << '\n';

	// shared_ptr::reset example
	std::shared_ptr<int> sp;	//empty
	sp.reset(new int);			//takes ownership of pointer
	*sp = 100;
	std::cout << *sp << '\n';
	sp.reset(new int);			//deletes managed object, acquires new pointer
	*sp = 200;
	std::cout << *sp << '\n';

	// shared_ptr::swap example
	std::shared_ptr<int> foo3(new int(101));
	std::shared_ptr<int> bar3(new int(201));
	foo3.swap(bar3);
	std::cout << "*foo3:" << *foo3 << '\t';
	std::cout << "*bar3:" << *bar3 << '\n';
	// shared_ptr::get example
	int *p = new int(10);
	std::shared_ptr<int> a(p);
	if(a.get() == p)
		std::cout << "a and p point to the same location\n";

	// three ways of accessing the same address:
	std::cout << *a.get() << "\t";
	std::cout << *a << "\t";
	std::cout << *p << "\n";
	// shared_ptr::operator*
	std::shared_ptr<int> foo4(new int);
	std::shared_ptr<int> bar4(new int(100));
	*foo4 = *bar4 * 2;
	std::cout << "foo4: " << *foo4 << '\t';
	std::cout << "bar4: " << *bar4 << '\n';
	// shared_ptr::operator->
	std::shared_ptr<C3> foo5;
	std::shared_ptr<C3> bar5(new C3);

	foo5 = bar5;

	foo5->a = 10;
	bar5->b = 20;

	if (foo5) std::cout << "foo5: " << foo5->a << ' ' << foo5->b << '\t';
	if (bar5) std::cout << "bar5: " << bar5->a << ' ' << bar5->b << '\n';
	// shared_ptr::unique
	std::shared_ptr<int> foo6;
	std::shared_ptr<int> bar6(new int);
	std::cout << "foo6 unique?\n" << std::boolalpha;
	std::cout << "1: " << foo6.unique() << '\t';  // false (empty)
	foo6 = bar6;
	std::cout << "2: " << foo6.unique() << '\t';  // false (shared with bar)
	bar6 = nullptr;
	std::cout << "3: " << foo6.unique() << '\n';  // true
	// example of shared_ptr::operator bool
	std::shared_ptr<int> foo7;
	std::shared_ptr<int> bar7(new int(34));
	if (foo7) std::cout << "foo7 points to " << *foo7 << '\n';
	else std::cout << "foo7 is null\n";

	if (bar7) std::cout << "bar7 points to " << *bar7 << '\n';
	else std::cout << "bar7 is null\n";

	// shared_ptr::owner_before
	int *p10 = new int(10);
	std::shared_ptr<int> a10(new int(20));
	std::shared_ptr<int> b10(a10, p10);  // alias constructor
	std::cout << "comparing a11 and b10...\n" << std::boolalpha;
	std::cout << "value-based: " << (!(a10 < b10) && !(b10 < a10)) << '\n';
	std::cout << "owner-based: " << (!a10.owner_before(b10) && !b10.owner_before(a10)) << '\n';

	delete p10;

    return 0;
}





运行效果:

参考:

https://cplusplus.com/reference/memory/shared_ptr/

std::shared_ptr - cppreference.com

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

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

相关文章

用Vite基于Vue3+ts+DataV+ECharts开发数据可视化大屏,即能快速开发又能保证屏幕适配

数据可视化大屏 基于 Vue3、Typescript、DataV、ECharts5 框架的大数据可视化&#xff08;大屏展示&#xff09;开发。此项目vue3实现界面&#xff0c;采用新版动态屏幕适配方案&#xff0c;全局渲染组件封装&#xff0c;支持数据动态刷新渲染、内部DataV、ECharts图表都支持自…

cad批量打印pdf怎么弄?介绍三种打印方法

cad批量打印pdf怎么弄&#xff1f;在CAD设计领域&#xff0c;批量打印PDF文件是一项常见且至关重要的任务。面对大量的CAD图纸&#xff0c;如何高效地进行转换和打印&#xff0c;成为了设计师们亟待解决的问题。今天&#xff0c;我们就来推荐三款能够批量打印PDF的CAD软件&…

又发现一款独立清理神器,界面清爽,功能强大,没有广告!

360清理Pro独立提取版是360公司推出的一款清理软件&#xff0c;主要用于清理系统垃圾和优化系统性能&#xff0c;涵盖了四大类型的清理场景&#xff0c;分别为&#xff1a;微信、QQ的垃圾扫描及清理&#xff0c;系统盘中的大文件、重复文件扫描及清理以及系统软件使用痕迹的清理…

【例子】webpack配合babel实现 es6 语法转 es5 案例 [通俗易懂]

首先来说一下实现 es6 转 es5 的一个简单步骤 1、新建一个项目&#xff0c;并且在命令行中初始化项目 npm init -y2、安装对应版本的 webpack webpack-cli(命令行工具) "webpack""webpack-cli"3、安装 Babel 核心库和相关的 loader "babel-core&qu…

容器之分栏窗体构件演示

代码; #include <gtk-2.0/gtk/gtk.h> #include <glib-2.0/glib.h> #include <gtk-2.0/gdk/gdkkeysyms.h> #include <stdio.h>int main(int argc, char *argv[]) {gtk_init(&argc, &argv);GtkWidget *window;window gtk_window_new(GTK_WINDO…

音乐管理系统

摘 要 现如今&#xff0c;在信息快速发展的时代&#xff0c;互联网已经成了人们在日常生活中进行信息交流的重要平台。看起来&#xff0c;听歌只是一种消遣和消遣&#xff0c;其实&#xff0c;只要你选对了曲子&#xff0c;就会产生许多不同的作用。音乐能舒缓身心&#xff0c…

北大推出全新机器人多模态大模型!面向通用和机器人场景的高效推理和操作

为了赋予机器人端到端的推理和操纵能力&#xff0c;本文创新性地将视觉编码器与高效的状态空间语言模型集成&#xff0c;构建了全新的 RoboMamba 多模态大模型&#xff0c;使其具备视觉常识任务和机器人相关任务的推理能力&#xff0c;并都取得了先进的性能表现。同时&#xff…

刷代码随想录有感(111):动态规划——零钱兑换II

干&#xff0c;被上了一课。注意题干&#xff0c;到底是求能装最大价值的方案还是装满这个容量共有多少种方法。他们的公式都不同&#xff0c;最大价值的方案是&#xff1a; dp[j] max(dp[j], dp[j - weight[i]] value[i]); 而装满有多少种方法是&#xff1a; dp[j] dp[j…

你不会是这样摆放 WiFi 路由器的吧?

当你购买WiFi路由器时&#xff0c;可能会对如何放置路由器以获得最好的信号覆盖感到迷茫。 那&#xff0c;到底要怎样摆放路由器&#xff0c;信号才会更好呢&#xff1f; 首先&#xff0c;咱们先简单了解一下天线信号是如何传输的。通常&#xff0c;天线信号是从天线垂直方向&a…

入门Ansible常用模块

自动化运维Devops-Ansible Ansible是新出现的自动化运维工具&#xff0c;基于Python 开发&#xff0c;集合了众多运维工具&#xff08;puppet 、cfengine、chef、func、fabric&#xff09;的优点&#xff0c;实现了批量系统配置 、批量程序部署、批量运行命令 等功能。Ansible…

PCL 拟合二维椭圆(迭代法)

文章目录 一、简介二、实现代码三、实现效果参考资料一、简介 一般情况,我们会用椭圆拟合二维点,用椭球拟合三维点。在n维中,这些对象被称为超椭球体,由二次方程隐式定义 超椭球的中心是n1向量C,nn矩阵S是正定的,n1向量X是超椭球上的任意点。矩阵S可以用特征分解,S = R…

洛谷 P1141 01迷宫 (dfs解决)

题目描述 有一个仅由数字 0 与 1 组成的 nn 格迷宫。若你位于一格 0 上&#xff0c;那么你可以移动到相邻 4 格中的某一格 1 上&#xff0c;同样若你位于一格 1 上&#xff0c;那么你可以移动到相邻 4 格中的某一格 0 上。 你的任务是&#xff1a;对于给定的迷宫&#xff0c;…

【2024德国工作】外国人在德国找工作是什么体验?

挺难的&#xff0c;德语应该是所有中国人的难点。大部分中国人进德国公司要么是做中国业务相关&#xff0c;要么是做技术领域的工程师。先讲讲人在中国怎么找德国的工作&#xff0c;顺便延申下&#xff0c;德国工作的真实体验&#xff0c;最后聊聊在今年的德国工作签证申请条件…

量子计算:1 从薛定谔的猫开始

大模型技术论文不断&#xff0c;每个月总会新增上千篇。本专栏精选论文重点解读&#xff0c;主题还是围绕着行业实践和工程量产。若在某个环节出现卡点&#xff0c;可以回到大模型必备腔调或者LLM背后的基础模型重新阅读。而最新科技&#xff08;Mamba,xLSTM,KAN&#xff09;则…

力扣爆刷第153天之TOP100五连刷(接雨水、环形链表、最长上升子序列)

力扣爆刷第153天之TOP100五连刷&#xff08;接雨水、环形链表、最长上升子序列&#xff09; 文章目录 力扣爆刷第153天之TOP100五连刷&#xff08;接雨水、环形链表、最长上升子序列&#xff09;一、300. 最长递增子序列二、415. 字符串相加三、143. 重排链表四、42. 接雨水五、…

后端实现预览pdf,mp4,图片

PDF预览 /*** pdf预览* param response*/RequestMapping(value "/preview")public void showPdf(HttpServletResponse response) {try {//String filePath this.getClass().getClassLoader().getResource("../../static/pdf/readme.pdf").getPath();Stri…

Python抓取高考网图片

Python抓取高考网图片 一、项目介绍二、完整代码一、项目介绍 本次采集的目标是高考网(http://www.gaokao.com/gkpic/)的图片,实现图片自动下载。高考网主页如下图: 爬取的流程包括寻找数据接口,发送请求,解析图片链接,向图片链接发送请求获取数据,最后保存数据。 二…

AGI 之 【Hugging Face】 的[ 简单介绍 ] [ 基础环境搭建 ] 的简单整理

AGI 之 【Hugging Face】 的[ 简单介绍 ] [ 基础环境搭建 ] 的简单整理 目录 AGI 之 【Hugging Face】 的[ 简单介绍 ] [ 基础环境搭建 ] 的简单整理 一、简单介绍 二、Hugging Face 三、环境搭建 python 环境的搭建 Pycharm 环境搭建 1、下载 Pycharm 安装包 2、安装 …

ADI Trinamic tmc2209专为3D打印和激光雕刻打造的高性能解决方案

TMC2209-LA是专为3D打印机和激光雕刻机设计的一款高性能、超静音的两相步进电机驱动器IC。该芯片结合了Trinamic公司的先进技术&#xff0c;为设备提供了稳定、可靠且低噪音的动力驱动解决方案 TMC2209-LA与许多传统驱动器以及TMC2208-LA引脚兼容。TRINAMICS先进的StealthChop2…

【嵌入式开发】UART

目录 一、概述 1.1 常见的通信类别/特点 1.2 常见几种通信 二、UART通信协议 2.1 UART通信介绍 2.2 UART通信协议 物理连接示意图&#xff1a; 三、STM32的UART接口 3.1 STM32的UART特点 3.2 STM32的UART框图分析 3.3 UART初始化步骤 3.4 STM32中UART使用 一、概述…