当前位置: 首页 > news >正文

C++--深度理解智能指针

PS:智能指针简单应用看这里  http://t.csdn.cn/qN7IK

1.智能指针的介绍

在C++中,智能指针有三个版本,分别为:

auto_ptr  unique_ptr shared_ptr 

这三个版本的智能指针中,shared_ptr最为完善,auto_ptr基本上没有太大用处,unique_ptr的使用场景并不多。对于智能指针来说,需要实现RAII和重载operator*和operator->,使它具有像指针一样的行为。

2.智能指针分析

    2.1 auto_ptr版本

        auto_ptr简单实现:

    template<class T>class Auto_ptr{public://管理权转移 auto_ptrAuto_ptr(T* ptr):_ptr(ptr){}Auto_ptr(Auto_ptr<T>& ptr):_ptr(ptr._ptr){ptr._ptr=nullptr;}T& operator=(const T& ptr){if (this != &ptr){if (_ptr){cout << "Delete:" << _ptr << endl;delete _ptr;}_ptr = ptr._ptr;ptr._ptr = nullptr;}return *this;}//析构函数需要写重载,不同常见需要不同析构函数/*~Auto_ptr(){if (_ptr){delete _ptr;}}*/T& operator*(){return *this;}T* operator->(){return this;}private:T* _ptr=nullptr;};

由于auto_ptr支持拷贝构造,为了确保指针所有者唯一,这里转移了所有权,转移所有权之后,导致了被拷贝的为空了,这是一大缺点,导致auto_ptr被遗弃。

2.2.unique_ptr的使用   

template<class T>class Unique_ptr{public:Unique_ptr(T* ptr):_ptr(ptr){}Unique_ptr(Auto_ptr<T>& ptr) = delete;T& operator=(const T& ptr) = delete;/*~Auto_ptr(){if (_ptr){delete _ptr;}}*/T& operator*(){return *this;}T* operator->(){return this;}private:T* _ptr = nullptr;};

    unique_ptr的底层直接没有使用拷贝构造和赋值重载,导致它只能使用在不需要拷贝构造和复制重载的场景上,所以unique_ptr的缺点为unique_ptr 不共享它的指针。 它无法复制到其它unique_ptr,无法通过值传递到函数,也无法用于需要副本的任何标准模板库 (STL) 算法。 只能移动unique_ptr 。 这意味着,内存资源所有权将转移到另一 unique_ptr,并且原始 unique_ptr 不再拥有此资源。

2.3 shared_ptr的使用

template<class T>class Shared_ptr{public:Shared_ptr(T* ptr=nullptr):_ptr(ptr),_Pcount(new int(1)){;}void Release(){if (--(*_Pcount) == 0){cout << "Delete:" << _ptr << endl;delete _ptr;delete _Pcount;}}~Shared_ptr(){Release();}Shared_ptr(Smart_ptr<T>& ptr):_ptr(ptr){(*_Pcount)++;ptr = nullptr;}Shared_ptr& operator=(Smart_ptr& ptr){if (_ptr == ptr._ptr)return *this;Release();--(*_Pcount);_ptr = ptr._ptr;_Pcount = ptr._Pcount;*_Pcount++;return *this;}T& operator*(){return *_ptr;}T* operator->(){return _ptr;}private:T* _ptr;int* _Pcount;};

在unique_ptr的基础上,新增加了一个版本,为shared_ptr版本。

基本原理:就是记录对象被引用的次数,当引用次数为 0 的时候,也就是最后一个指向该对象的共享指针析构的时候,共享指针的析构函数就把指向的内存区域释放掉。

特点:它所指向的资源具有共享性,即多个shared_ptr可以指向同一份资源,并在内部使用引用计数机制来实现这一点。

共享指针内存:每个 shared_ptr 对象在内部指向两个内存位置:

  • 指向对象的指针;
  • 用于控制引用计数数据的指针。

当新的 shared_ptr 对象与指针关联时,则在其构造函数中,将与此指针关联的引用计数增加1。

当任何 shared_ptr 对象超出作用域时,则在其析构函数中,它将关联指针的引用计数减1。如果引用计数变为0,则表示没有其他 shared_ptr 对象与此内存关联,在这种情况下,它使用delete函数删除该内存。

shared_ptr像普通指针一样使用,可以将*和->与 shared_ptr 对象一起使用,也可以像其他 shared_ptr 对象一样进行比较。

但是,对于shared_ptr来说,依然有一个缺点,如果是循环引用,那么将会出现bug,这时候就需要使用weak_ptr.

2.4 weak_ptr使用

weak_ptr是一个弱引用的智能指针,它可以与shared_ptr一起使用。weak_ptr不会增加所管理的对象的引用计数,因此它不会影响对象的生命周期。可以通过weak_ptrlock()成员函数来获取一个指向所管理的对象的shared_ptr

3.总结:

3.1 智能指针原理:

智能指针解决问题的思想:将常规指针进行包装,当智能指针对象过期时,让它的析构函数对常规指针进行内存释放。

auto_ptr(C++98的方案,C++11已经废弃):采用所有权模式,对于特定的对象,只能有一个智能指针可拥有它,这样只有拥有对象的智能指针的析构函数会删除该对象。然后,让赋值操作转让所有权。

unique_ptr(替代 auto_ptr):也是采用所有权模式,实现独占式拥有或严格拥有概念,保证同一时间内只有一个智能指针可以指向该对象。

shared_ptr:采用引用计数实现共享式拥有概念。多个智能指针可以指向相同对象,该对象和其相关资源会在最后一个引用被销毁时候释放。它使用引用计数来表明资源被几个指针共享。例如,赋值时,计数将加 1,而指针过期时,计数将减 1。仅当最后一个指针过期时,才调用 delete。

weak_ptr:该类型指针通常不单独使用(没有实际用处),只能和 shared_ptr 类型指针搭配使用。weak_ptr 类型指针并不会影响所指堆内存空间的引用计数,可以用来解决循环引用问题。

3.2 使用场景

如果在程序中使用new 从堆(自由存储区)分配内存,等到不再需要时,应使用 delete 将其释放,如果忘记释放,则会产生内存泄露。C++ 引入了智能指针, 以帮助自动完成这个过程。智能指针是行为类似于指针的类对象。如果程序要使用多个指向同一个对象的指针,应该选择shared_ptr;如果程序不需要多个指向同一个对象的指针,则可以使用unique_ptr;如果使用new [] 分配内存,应该选择 unique_ptr;如果函数使用new 分配内存,并返回指向该内存的指针,将其返回类型声明为 unique_ptr 是不错的选择。

相关文章:

C++--深度理解智能指针

PS:智能指针简单应用看这里 http://t.csdn.cn/qN7IK 1.智能指针的介绍 在C中&#xff0c;智能指针有三个版本&#xff0c;分别为&#xff1a; auto_ptr unique_ptr shared_ptr 这三个版本的智能指针中&#xff0c;shared_ptr最为完善&#xff0c;auto_ptr基本上没有太大用…...

Spring Boot使用MySQL的默认连接池

笔者在近期秋招面试的时候被问到了这个问题&#xff0c;现在简单梳理一下便于后期重新回顾&#xff0c;并加深记忆。 Spring Boot 默认使用的数据库连接池是 HikariCP(开源库地址)。 HikariCP 是目前性能最好的连接池之一&#xff0c;它具有高度的性能、可靠性和可扩展性&…...

conda使用教程

Conda介绍 conda可以理解为一个工具&#xff0c;也是一个可执行命令&#xff0c;其核心功能是包管理和环境管理。包管理与pip的使用方法类似似&#xff0c;环境管理则是允许用户方便滴安装不同版本的python环境并在不同环境之间快速地切换。 conda的设计理念 conda将几乎所有…...

什么是LLM大语言模型?

什么是LLM大语言模型&#xff1f; 大语言模型&#xff08;英文&#xff1a;Large Language Model&#xff0c;缩写LLM&#xff09;&#xff0c;也称大型语言模型&#xff0c;是一种人工智能模型&#xff0c;旨在理解和生成人类语言。它们在大量的文本数据上进行训练&#xff0…...

jenkins同一jar包部署到多台服务器

文章目录 安装插件配置ssh服务构建完成后执行 没有部署过可以跟这个下面的步骤先部署一遍&#xff0c;我这篇主要讲jenkins同一jar包部署到多台服务器 【Jenkins】部署Springboot项目https://blog.csdn.net/qq_39017153/article/details/131901613 安装插件 Publish Over SSH 这…...

(四)Doceke安装MySQL镜像+Docker启动MySQL容器

Doceke安装MySQL镜像/Docker启动MySQL容器 一、doceke安装MySQL镜像 切换到root用户&#xff0c;su root 。 1、启动Docker 启动&#xff1a;sudo systemctl start docker 停止&#xff1a;systemctl stop docker 重启&#xff1a;systemctl restart docker 查看docker运行…...

Android Studio:Could not initialize class org.codehaus.groovy.vmplugin.v7.Java7

原项目使用jdk8&#xff0c;升级gradle后出现的该问题。 java.lang.NoClassDefFoundError: Could not initialize class org.codehaus.groovy.vmplugin.v7.Java7at org.codehaus.groovy.vmplugin.VMPluginFactory.<clinit>(VMPluginFactory.java:43)at org.codehaus.gro…...

Spring Clould 搜索技术 - elasticsearch

视频地址&#xff1a;微服务&#xff08;SpringCloudRabbitMQDockerRedis搜索分布式&#xff09; 初识ES-什么是elasticsearch&#xff08;P77&#xff0c;P78&#xff09; 1.elasticsearch的作用 elasticsearch是一款非常强大的开源搜索引擎&#xff0c;具备非常多强大功能…...

android核绑定cpuset配置与检测进程所在核cpuset方法

一、开机阶段 开机有如下阶段。抛开开机动画需要的audio、surfaceflinger等进程&#xff0c;大部分android程序是在/data分区加载完整以后开始加载。所以cpuset的配置可以在 post-fs-data之后。注意&#xff0c;init.rc的不同阶段脚本都可能覆盖前面配置的cpuset。配置好检查与…...

Lnton羚通关于如何使用nanoPC-T4 安装OpenCV?

nanoPC-T4 安装 OpenCV Note: OpenCV has been pre-installed in FriendlyCore/FriendlyDesktop (Version after 201905) and does not require manual installation. Please download the latest FriendlyCore/FriendlyDesktop Image file from the following URL: http://do…...

内存泄漏:前端开发者的噩梦——内存泄露的原因及排查

在前端开发中&#xff0c;内存泄漏是一个常见但令人头疼的问题。它会导致应用程序变得缓慢&#xff0c;不稳定&#xff0c;最终可能崩溃。本文将介绍内存泄漏的概念、常见泄漏原因以及如何排查和预防内存泄漏。 什么是内存泄漏&#xff1f; 内存泄漏是指应用程序中的内存被错…...

高效使用ChatGPT之ChatGPT客户端

ChatGPT客户端&#xff0c;支持Mac, Windows, and Linux 下载地址见文章结尾 软件截图 Windows: Mac&#xff1a; 说明 chatgpt桌面版&#xff0c;相比于网页版的chatgpt&#xff0c;最大的特色是支持历史聊天对话记录导出&#xff0c;且支持三种格式&#xff1a;PNG、PDF、…...

【腾讯云 TDSQL-C Serverless 产品体验】基于TDSQL-C 存储爬取的QQ音乐歌单数据

【腾讯云 TDSQL-C Serverless 产品体验】基于TDSQL-C 存储爬取的QQ音乐歌单数据 文章目录 【腾讯云 TDSQL-C Serverless 产品体验】基于TDSQL-C 存储爬取的QQ音乐歌单数据前言出现的背景一、TDSQL-C数据库是什么&#xff1f;二、TDSQL-C 的特点三、TDSQL-C的应用场景四、基于TD…...

leetcode 6450. k-avoiding 数组的最小总和

给你两个整数 n 和 k 。 对于一个由 不同 正整数组成的数组&#xff0c;如果其中不存在任何求和等于 k 的不同元素对&#xff0c;则称其为 k-avoiding 数组。 返回长度为 n 的 k-avoiding 数组的可能的最小总和。 示例 1&#xff1a; 输入&#xff1a;n 5, k 4 输出&#…...

变压器绝缘油耐压试验

试验目的 绝缘油是电气设备常用的绝缘、 灭弧和冷却介质。 为保证它在运行过程中具有良好的性能&#xff0c; 必须定期对其进行各项试验&#xff0c; 尤其是耐压试验。 绝缘油的耐压试验是在专用的击穿电压试验器中进行的&#xff0c; 试验器包括一个瓷质或玻璃油杯、 两个直径…...

Windows控制台API官方文档

2023年8月21日&#xff0c;周下午 中文文档&#xff1a;控制台函数 - Windows Console | Microsoft Learn 英文文档&#xff1a;Console Functions - Windows Console | Microsoft Learn...

PyTorch DataLoader 报错 “DataLoader worker exited unexpectedly“ 的解决方案

注意&#xff1a;博主没有重写d2l的源代码文件&#xff0c;而是创建了一个新的python文件&#xff0c;并重写了该方法。 一、代码运行日志 C:\Users\Administrator\anaconda3\envs\limu\python.exe G:/PyCharmProjects/limu-d2l/ch03/softmax_regression.py Traceback (most r…...

【AI绘画--七夕篇】:七夕特别教程,使用SDXL绘制你的心上人(Stable Diffusion)(封神榜—妲己)

目录 前言0、介绍0-0、结果展示0-1、Stable Diffusion0-2、sdxl介绍 一、云端部署Stable Diffusion1-1、云端平台的优势 二、平台介绍三、注册账号并且开始炼制3-1、购买算力并创建工作空间3-2、启动工作空间3-3、应用市场一键安装3-4、使用Stable-Diffusion作图 四、有女朋友的…...

hadoop2的集群数据将副本存储在hadoop3

在 Hadoop 集群中&#xff0c;HDFS 副本是分布式存储的&#xff0c;会存储在不同的节点上。因此&#xff0c;如果您的 HDFS 所在路径是在 Hadoop2 集群中&#xff0c;您可以在 Hadoop3 集群上添加新的节点&#xff0c;并向 Hadoop3 集群中添加这些新节点上的数据副本。 以下是…...

c# ??=

空合并运算符 ??&#xff0c;用于定义引用类型和可空类型的默认值。如果此运算符的左操作符不为Null&#xff0c;则此操作符返回左操作数&#xff0c;否则返回右操作数。 例如&#xff1a; //当a不为空时返回a&#xff0c;为null时返回b var c a ?? b;空合并赋值运算符??…...

ABAP - MEMORY ID 的跨程序数据共享实践

1. ABAP内存ID&#xff1a;跨程序数据共享的秘密武器 在SAP开发中&#xff0c;经常会遇到这样的场景&#xff1a;程序A需要某些数据&#xff0c;但获取这些数据的逻辑写在程序B里。传统做法可能是通过接口、数据库表或者文件来中转数据&#xff0c;但这些方法要么太麻烦&#x…...

保姆级教程:用命令行实时监控瑞芯微RK3588的CPU/GPU/NPU负载与温度

嵌入式开发实战&#xff1a;构建RK3588芯片全维度性能监控系统 在边缘计算和AI推理场景中&#xff0c;RK3588作为一款高性能SoC&#xff0c;其复杂的多核架构&#xff08;包括6核CPU、Mali-G610 GPU和6TOPS NPU&#xff09;对系统监控提出了更高要求。本文将手把手教你搭建一个…...

【实战解析】PVE无显卡启动后网络失联:从硬件自检到系统绑定的完整排障指南

1. 无显卡启动的硬件准备与BIOS调试 当你准备在Proxmox VE&#xff08;PVE&#xff09;环境下实现无显卡启动时&#xff0c;首先要确保硬件层面支持这个特性。我遇到过不少用户直接拔掉显卡就期待系统能正常启动&#xff0c;结果发现连最基本的网络连接都失效了。这其实是个典型…...

OpenClaw常用命令与在Windows下安装Tavily-Search

目录1. Windows安装Tavily-Search2. 启动与关闭2.1 正常流程2.2 故障处理3. 模型切换1. Windows安装Tavily-Search 确保目录位于C:\Users\用户名运行命令npx clawhub install openclaw-tavily-search在C:\Users\用户名\.openclaw创建文件.env用记事本打开.env&#xff0c;写入…...

LeagueAkari终极指南:智能游戏辅助工具快速上手与深度配置

LeagueAkari终极指南&#xff1a;智能游戏辅助工具快速上手与深度配置 【免费下载链接】League-Toolkit 兴趣使然的、简单易用的英雄联盟工具集。支持战绩查询、自动秒选等功能。基于 LCU API。 项目地址: https://gitcode.com/gh_mirrors/le/League-Toolkit 你是否曾在…...

OpenClaw备份方案:GLM-4-7-Flash自动加密重要文件并上传网盘

OpenClaw备份方案&#xff1a;GLM-4-7-Flash自动加密重要文件并上传网盘 1. 为什么需要自动化加密备份 去年的一次硬盘故障让我损失了三个月的项目资料&#xff0c;这件事彻底改变了我对数据安全的认知。传统备份方案要么需要手动操作&#xff08;容易遗忘&#xff09;&#…...

高效安全备份QQ空间历史说说:GetQzonehistory智能工具全指南

高效安全备份QQ空间历史说说&#xff1a;GetQzonehistory智能工具全指南 【免费下载链接】GetQzonehistory 获取QQ空间发布的历史说说 项目地址: https://gitcode.com/GitHub_Trending/ge/GetQzonehistory 在数字记忆日益珍贵的今天&#xff0c;QQ空间作为承载无数青春回…...

吃透MQ:从原理到落地,解决分布式系统的核心痛点

在分布式系统与微服务架构普及的今天&#xff0c;“高并发、高可用、低耦合”成为系统设计的核心诉求。而消息队列&#xff08;Message Queue&#xff0c;简称MQ&#xff09;&#xff0c;作为分布式架构中的“通信枢纽”&#xff0c;凭借异步通信、流量削峰、系统解耦等核心能力…...

微软服软!被骂5年的Win11将被“整改”:告别强制更新、减少Copilot、任务栏摆放自由

整理 | 屠敏出品 | CSDN&#xff08;ID&#xff1a;CSDNnews&#xff09;Windows 11 自 2021 年发布以来&#xff0c;因任务栏功能缩水、UI 不统一、强制网络登录以及更高的硬件门槛&#xff0c;成为用户集中吐槽的焦点。再加上近来微软猛推 AI 功能&#xff0c;Copilot 的入口…...

后端架构师转型AI智能体架构师:3个月实战路径,收藏这份落地指南

如果你本身就是后端/全栈/架构师出身&#xff0c;这意味着你已经有了一套非常扎实的“确定性系统”的构建能力——分布式、高并发、数据库事务、系统稳定性&#xff0c;这些都是你的底牌。 而AI智能体恰恰是“不确定性系统”&#xff08;大模型&#xff09;与“确定性系统”&am…...