C/C++智能指针详解

news2024/9/24 7:25:09

系列文章目录

文章目录

  • 系列文章目录
  • 前言
  • 一、什么是智能指针?
  • 二、使用方法
    • 1.shared_ptr
    • 2.unique_ptr
    • 3.weak_ptr


前言

对C/C++学习感兴趣的可以看看这篇文章哦:C/C++教程

本章主要介绍一些C/C++中智能指针的实现原理以及如何使用

一、什么是智能指针?

C/C++中,指针是一个非常重要的概念,其强大但也麻烦

麻烦之处就在于一旦你申请了内存,那就必须要手动去释放内容,否则就会造成内存泄漏

当然了,在代码量少的情况下你可能会不以为意,因为这点内存即使泄露了也根本看不出来,而且一旦程序执行结束,所有内存都会被系统释放

但如果一旦写比较大点的项目,内存管理就显得很重要了,比如QQ,微信等等,一般都是一直挂着的

如果挂几个小时就把电脑内存耗干净了,瞬间电脑变卡,谁还用啊

所以智能指针的作用就是防止我们麻痹大意忘记释放内存,帮助我们管理内存的

当然也有多次释放一个指针,导致程序崩溃的问题也能就此解决

二、使用方法

虽然智能指针听着很高级,但使用起来并不算复杂,熟悉之后,其实和普通指针差别不大。但会更加好用

自C++11之后,智能指针共有三个:shared_ptrunique_ptrweak_ptr

1.shared_ptr

看名字就知道,它是可以分享的指针,其使用方法很简单:

比如这里有一个类:

class User {
public:
	User() {
		cout << "这是构造函数" << endl;
	}
	~User()
	{
		cout << "这是析构函数" << endl;
	}

	void TestFun() {
		cout << "这是一个测试函数" << endl;
	}

};

然后使用共享智能指针:

#include<iostream>
using namespace std;
//上面的那个类可以放在这里
int main() {
	shared_ptr<User> p(new User());
	shared_ptr<User> p1 = p;
	shared_ptr<User> p2 = p;

	p->TestFun(); //调用函数的方式和指针一样
	cout << p.use_count() << endl; //输出共享个数
}

即:通过模板参数,传入要构造的指针类型,然后在初始化的时候,就可以直接new一个对象即可

因为是共享的,所以它还能互相赋值,并可以用函数use_count返回当前共享的个数

其使用方法,如调用类的函数和属性之类的,就和普通的指针一样,用->进行调用即可,但是却不需要我们去亲自清理内存了!

在这里插入图片描述
看,现在我们并没有清理内存,但这个类的析构函数却被调用了!这就说明内存已经被正常释放了

这就是智能指针的好处!

但智能指针写着有点麻烦,每次声明其类型都有一长串,所以一般我们会对指针进行重定义,达到简化的目的:

typedef shared_ptr<User> SPUser;
int main() {
	SPUser p(new User());
	SPUser p1 = p;
	SPUser p2 = p;
	p->TestFun(); //调用函数的方式和指针一样
	cout << p.use_count() << endl; //输出共享个数
}

2.unique_ptr

上面的共享指针的使用方法和普通指针区别并不大

但有时候,我们想要某个对象同时只能存在一份,即不允许像共享指针那样,可以到处随意赋值给别人

这时候就可以用unique_ptr,其使用方法如下:

typedef unique_ptr<User> UPUser; //重新定义一个名称,便于使用
int main() {
	UPUser p(new User);
	//UPUser p1 = p; //错误,不能进行赋值
	UPUser p2;
	p2.swap(p); //但可以交换,即p2现在保存有变量,但p变为了空指针
	if (p == nullptr) {
		cout << "p为空指针" << endl;
	}
	p2->TestFun(); //正常调用

	UPUser p3 = move(p2); //也可以用move函数移动
	if (p2 == nullptr) { //此时p2就是空指针
		cout << "p2为空指针" << endl;
	}
	p3->TestFun(); //p3则保存对象指针
}

在这里插入图片描述

可以看到,它的使用方法其实和共享指针是差不多的,唯一不同之处就是,它内部的指针值,同一时刻只能存在一份

即,你不能对它进行任何形式的复制,但是可以移动

3.weak_ptr

这个智能指针用的不太多,因为它本身并没有太多实际的用途,而是主要作为shared_ptr的一个辅助类存在

比如有多少指向相同的 shared_ptr 指针、shared_ptr 指针指向的堆内存是否已经被释放等等。

其使用方法如下:

typedef shared_ptr<User> SPUser;
typedef weak_ptr<User> WPUser;
int main() {
	
	SPUser p(new User());
	SPUser p1 = p;
	SPUser p2 = p;

	WPUser wp(p);
	cout << wp.use_count() << endl; //查看这个共享指针使用次数
	cout << wp.expired() << endl; //判断这个指针是否为空,或者内存已经被释放

}

在这里插入图片描述

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

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

相关文章

计算机组成原理复习:存储器系统

计算机组成原理复习&#xff1a;存储器系统3.1 存储器的层次化结构3.2 半导体随机存储器&#xff08;RAM&#xff0c;易失性存储器&#xff09;3.2.1 静态随机存储器&#xff08;SRAM&#xff09;3.2.2 动态随机存储器&#xff08;DRAM&#xff09;3.2.3 只读存储器&#xff08…

token认证、Express中实现token的过程

一、token认证 1. 什么是token token的意思是“令牌"&#xff0c;是服务端生成的一串字符串&#xff0c;作为客户端进行请求的一个标识。当用户第一次登录后&#xff0c;服务器生成一个token并将此token返回给客户端&#xff0c;以后客户端只需带上这个token前来请求数据…

Jenkins搭建 笔记总结

文章目录1. 什么是CI/CD(DI)&#xff1f;2. 环境 安装部署3. 搭建 GitLab服务器&#xff08;ssh方式搭建&#xff09;4. 搭建 GitLab服务器&#xff08;Docker方式搭建&#xff09;4.1 搭建Docker环境4.2 docker容器 安装gitlab5. GitLab 提交代码6. Jenkins 配置Maven Git自动…

【信息论与编码 沈连丰】第五章:离散信道及其信道编码

【信息论与编码 沈连丰】第五章&#xff1a;离散信道及其信道编码第五章 离散信道及其信道编码5.1 信道的分类及其描述5.2 无扰离散信道的传输特性5.3 有扰离散信道的传输特性5.4 译码准则5.5 有扰离散信道的信道编码定理5.6 信道编码定理的应用第五章 离散信道及其信道编码 5…

6\8. 语义分析和中间代码生成

6&8. 语义分析和中间代码生成 从几个问题说起&#xff1a; 要计算 34*5 的值如何计算&#xff1f;按照以前的方法&#xff0c;我们会想到利用符号栈和数值栈来完成这个运算。但是有了语法分析之后我们不再需要进行这么复杂的代码构造了。第一&#xff0c;我们可以使用自顶…

AcWing1206.剪格子——学习笔记(未AC)

题目&#xff1a;1206. 剪格子 - AcWing题库https://www.acwing.com/problem/content/description/1208/ import java.util.Scanner;public class Main {public static void main(String args[]){//读数据Scanner input new Scanner(System.in);String MN input.nextLine();S…

Apache ShardingSphere分表的简单使用和常见问题

目录 简介 什么是 Apache ShardingSphere? 分库分表的背景 使用 pom 配置 1&#xff0c;application.properties配置文件 2&#xff0c;创建配置类 分表 验证分表 常见问题 自定义分表规则未生效 简介 官网&#xff1a;Apache ShardingSphere 版本&#xff1a;4…

ArcGIS基础实验操作100例--实验42创建渔网Fishnet

本实验专栏参考自汤国安教授《地理信息系统基础实验操作100例》一书 实验平台&#xff1a;ArcGIS 10.6 实验数据&#xff1a;请访问实验1&#xff08;传送门&#xff09; 高级编辑篇--实验42 创建渔网Fishnet 目录 一、实验背景 二、实验数据 三、实验步骤 &#xff08;1&a…

深度学习推理框架调研总结

深度学习推理框架1.移动端深度学习推理框架调研1.1 小米的MACE&#xff08;2017&#xff09;1.2 阿里的MNN1.3 腾讯的TNN1.4 ARM的tengine1.5 百度的paddle-mobie1.6 Facebook的Caffe2&#xff08;*&#xff09;1.7 Google的TensorFlow Lite &#xff08;*&#xff09;1.8 Appl…

南京晓庄操作系统期末复习【背诵部分】

操作系统期末复习背诵部分第一章1.操作系统的特征&#xff1a;2.操作系统的最基本特征是什么&#xff0c;为什么3.操作系统的目标4.操作系统的主要功能5.计算机资源6.多道程序设计时应解决什么问题7.三种操作系统及特点第二章1.进程的定义2.进程的特征3.进程的三种基本状态4.进…

Spark04: Transformation与Action开发

一、创建RDD的三种方式 RDD是Spark编程的核心&#xff0c;在进行Spark编程时&#xff0c;首要任务是创建一个初始的RDD这样就相当于设置了Spark应用程序的输入源数据然后在创建了初始的RDD之后&#xff0c;才可以通过Spark 提供的一些高阶函数&#xff0c;对这个RDD进行操作&a…

python学生管理系统(pyqt5 含界面)

学生管理系统项目流程 项目模块 账号登陆 人脸识别 增添学生信息 删除学生信息 改动学生信息 查询学生信息 项目主体框架 app.py为主代码&#xff0c;负责用于界面打开展示。img文件夹负责放置项目qrc的图像page文件夹为单独页面的类plugin文件夹为功能模块的类ui文件夹…

机器人中的数值优化|【一】数值优化基础

数值优化基础 凸集 Convex Sets 凸集的定义 令X是线性空间。如果对于X的子集S中的所有x和y&#xff0c;并且在区间 [0,1]中的所有t&#xff0c;点 (1−t)xty(1-t)x ty(1−t)xty也属于S&#xff0c;则S称为凸集。 不失一般性&#xff0c;对于所有的凸集&#xff0c;其线性组…

Zookeeper详解(二)——API 事件监听

Java API znode是zooKeeper集合的核心组件&#xff0c;zookeeper API提供了一小组方法使用zookeeper集合来操纵znode的所有细节。 客户端应该遵循以下步骤&#xff0c;与zookeeper服务器进行清晰和干净的交互。 连接到zookeeper服务器。zookeeper服务器为客户端分配会话ID。…

uniapp 之 接入小程序客服

目录 前言 小程序客服 代码只需要一步 配置也需要一步​​​​​​​ 前言 小程序客服 因老大 看到别人家有在线客服这个功能&#xff0c;就让我也做一个&#xff0c;这个功能很简单 效果图1 代码只需要一步 <button type"default" open-type"con…

MATLAB | 绘图复刻(六) | 分组环形热图

有粉丝问我Ecology Letters, (2021) 24: 1018–1028 Soil carbon persistence governed by plant input and mineral protection at regional and global scales 这篇文章中的Figure 2咋画&#xff0c;原图长这样&#xff1a; 复刻效果&#xff1a; 完整步骤 0 数据定义 按…

node.js创建网站实例1

1.node.js安装 我的电脑环境&#xff1a;win10 网址&#xff1a;https://nodejs.org/en/ 我下载了18.12.1版本 一路next默认安装&#xff0c;安装完成后&#xff0c;运行cmd&#xff0c;查看版本号 会同时安装npm&#xff0c;也可以同时查看版本号 2.创建第一个网站实例hell…

内卷对于2022是一种无奈,也是一种修行

其实我们谁也不知道2023年对于我们普通的开发人员来说会有什么样的试炼&#xff0c;因为2022年身边有太多的人&#xff0c;为了工作&#xff0c;为了生活&#xff0c;为了家庭&#xff0c;为了理想&#xff0c;不得不选择走向别人看似很卷的那条路。 对于我们周围的人来说&…

【Vim】基本操作及命令集详解

概述 Vim 是从 vi 发展出来的一个文本编辑器。vi 内置在Linux系统中&#xff0c;是vim的简化版编辑器&#xff0c;vim则需要进行安装使用。Vim代码补全、编译及错误跳转等方便编程的功能特别丰富&#xff0c;可以实现高效率移动和高效的输入&#xff0c;在程序员中被广泛使用。…

CPT203-Software Engineering(3)

文章目录9. Software Design9.1 Architecture Design9.1.1 Architectural patterns9.2 Component-level Design9.2.1 Component9.2.2 Views of component9.2.3 Component-level design process9.3 User Interface Design9.3.1 Interface Design Process9.3.2 Interface Design …