【C++11新特性】详解智能指针 创建、使用、注意事项

创作不易,本篇文章如果帮助到了你,还请点赞 关注支持一下♡>𖥦<)!!
主页专栏有更多知识,如有疑问欢迎大家指正讨论,共同进步!
🔥c++系列专栏:C/C++零基础到精通 🔥

给大家跳段街舞感谢支持!ጿ ኈ ቼ ዽ ጿ ኈ ቼ ዽ ጿ ኈ ቼ ዽ ጿ ኈ ቼ ዽ ጿ ኈ ቼ

在这里插入图片描述

c语言内容💖:

专栏:c语言之路重点知识整合

【c语言】全部知识点总结


目录

  • 一、 auto_ptr
  • 二、unique_ptr
  • 三、shared_ptr
  • 四、weak_ptr

C++11 中引入了智能指针,便于进行内存管理

使用智能指针 需要包含头文件: #include <memory> 以及 std 命名空间

智能指针会自动回收空间,不需要担心内存泄漏问题


四种智能指针:

  • auto_ptr(C++11 被弃用)
  • unique_ptr
  • shared_ptr
  • weak_ptr

一、 auto_ptr

创建auto_ptr对象的三种方式:

#include <iostream>
#include <memory>
using namespace std;class A
{
public:void fun(){cout << this << "A::fun()" << endl;}
};int main()
{auto_ptr<A> p1(new A() );auto_ptr<A> p2;p2.reset(new A()); auto_ptr<A> p3;p3 = p1;	//把p1空间的归属权交给p3,后面不能再用p1return 0;
}

使用对象:

p3.get()->fun();p3->fun();

auto_ptr 存在的问题:将 p1 赋值给 p3 ,会将 p1 的资源转交给 p3,而不是复制,此时再调用 p1会出现空指针问题:

auto_ptr<A> p3;
p3 = p1;	
p1->fun();	//error

因此在 C++11 中被弃用。

二、unique_ptr

唯一所属权的智能指针,只能有一个指针管理内存

三种创建对象与使用方式:

#include <iostream>
#include <memory>
using namespace std;class A
{
public:void fun(){cout << this << "A::fun()" << endl;}
};int main()
{//1.unique_ptr<A> p1(new A());p1->fun();//2.resetunique_ptr<A> p2;p2.reset(new A());p2.get()->fun();//3.moveunique_ptr<A> p3;p3 = std::move(p2);	//使用权传递,不可以直接使用 = 赋值(*p3).fun();cout << p2.get() << endl;// 4.make_unqiueunique_ptr<A> p4 = make_unique<A>();    //c++14引入return 0;
}

image.png

C++11中unique_ptr 用于替代废弃的auto_ptr

空间使用权传递的方式要求更严格:不可以直接使用 = 赋值,可以使用 std::move 将左值转为右值进行赋值

同时,当一个unique_ptr的使用权被交出后或者超出智能指针的作用域后,这个指针会自动失效

image.png

但是 unique_ptr 一个只能指向一块空间,如果 reset 转移到另一块空间,原先的内存就无法指向使用了,因此引入了 shared_ptr:

三、shared_ptr

共享所属权的智能指针

多个指针可以指向同一个空间,可以同时生效

使用引用计数管理回收 ,使用 use_count函数可以查看指向这块空间的指针数量

#include <iostream>
#include <memory>
using namespace std;class A
{
public:void fun(){cout << "A::fun()" << endl;}~A(){cout << "A::~A()" << endl;}
};int main()
{shared_ptr<A> p1(new A());p1->fun();shared_ptr<A> p2;p2.reset(new A());(*p2).fun();shared_ptr<A> p3;p3 = make_shared<A>();p3.get()->fun();{shared_ptr<A> p4;p4 = p3; // 指向同一块空间 两个指针共享内存cout << p4.use_count() << endl;cout << "p3: " << p3.get() << " p4: " << p4.get() << endl;} // p4在此回收return 0;
}

image.png

shared_ptr 存在循环引用的问题:

如果两个 shared_ptr 相互引用,引用计数永远不会变为0,因此它们所指向的对象也不会被删除,这会导致内存泄漏

例如:

#include <iostream>
#include <memory>
using namespace std;class B;
class A
{
public:shared_ptr<B> pb;void fun(){cout << "A::fun()" << endl;}~A(){cout << "A::~A()" << endl;}
};class B
{
public:shared_ptr<A> pa;void fun(){cout << "B::fun()" << endl;}~B(){cout << "B::~B()" << endl;}
};int main()
{shared_ptr<A> pa = make_shared<A>();shared_ptr<B> pb = make_shared<B>();pa->pb = pb;pb->pa = pa;pb->fun();pa->fun();// pa和 pb 的引用计数都是 1,但由于它们相互引用,它们都不会被删除return 0;
}

image.png
为了解决循环引用的问题,引入了 weak_ptr

四、weak_ptr

用于解决shared_ptr存在循环引用的问题

弱引用计数的共享使用权的智能指针,不能独立存在,配合shared_ptr使用

如果使用 weak_ptrshared_ptr指向同一空间,引用计数不会加1

#include <iostream>
#include <memory>
using namespace std;class B;
class A;class A
{
public:shared_ptr<B> pb;void fun(){cout << "A::fun()" << endl;}~A(){cout << "A::~A()" << endl;}
};class B
{
public:weak_ptr<A> pa; //使用weak_ptrvoid fun(){cout << "B::fun()" << endl;}~B(){cout << "B::~B()" << endl;}
};int main()
{shared_ptr<A> pa = make_shared<A>();shared_ptr<B> pb = make_shared<B>();pa->pb = pb;pb->pa = pa;pb->fun();pa->fun();return 0;
}

image.png

weak_ptr 注意事项

  • 避免悬空指针 使用 weak_ptr 之前,必须确保其所指向的对象仍然存在
  • std::weak_ptr 应该通过 shared_ptr 构造而来,不可直接从裸露指针构造
  • 注意失效 当最后一个 shared_ptr 所引用的对象被释放时,weak_ptr 会自动失效

在这里插入图片描述

大家的点赞、收藏、关注将是我更新的最大动力! 欢迎留言或私信建议或问题。
大家的支持和反馈对我来说意义重大,我会继续不断努力提供有价值的内容!如果本文哪里有错误的地方还请大家多多指出(●'◡'●)

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

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

相关文章

小白如何学鸿蒙开发?

在互联网技术不断发展的现在&#xff0c;鸿蒙操作系统的出现标志着是能技术领域的一次重大突破&#xff0c;鸿蒙作为华为推出的一代操作系统&#xff0c;鸿蒙不仅达代表了自主创新的力量&#xff0c;还因为独特的分布式架构和全场景适配能力而备受关注。随着鸿蒙生态的不断完善…

测试架构师必备技能 —— Nginx安装部署实战

Nginx("engine x")是一款是由俄罗斯的程序设计师Igor Sysoev所开发高性能的免费开源Web和 反向代理服务器&#xff0c;也是一个 IMAP/POP3/SMTP 代理服务器。在高并发访问的情况下&#xff0c;Nginx是Apache服务器不错的替代品。官网数据显示每秒TPS高达50W左右。本文…

左旋字符串解析

题目 实现一个函数&#xff0c;可以左旋字符串中的k个字符。 例如&#xff1a; ABCD左旋一个字符得到BCDA ABCD左旋两个字符得到CDAB 法1&#xff1a;一个个移动 #include<stdio.h> #include<string.h>//把一个字符串s,左移time个字符 void leftRound(char* s…

leetcode日记(26)有效的数独

用暴力解法解出来的&#xff0c;判断3*3那要写的比较多&#xff0c;判断竖列那花了点功夫。 不知道有没有更好的解法。 class Solution { public:bool isValidSudoku(vector<vector<char>>& board) {for(int i0;i<9;i){vector<char>cboard[i];for(i…

[Docker实战] 旭日X3派上Docker Openwrt +Samba 实现局域网NAS 开启AP模式

​ &#x1f308; 博客个人主页&#xff1a;Chris在Coding &#x1f3a5; 本文所属专栏&#xff1a;[旭日X3派] [Docker实战] ❤️ 前置学习专栏&#xff1a;[Linux学习] ⏰ 我们仍在旅途 …

创建补丁文件.patch

前言 在linux中&#xff0c;在工程实践中。 自己基于文件1进行了修改&#xff0c;得到文件2&#xff0c;文件1有线上仓库。时常会遇到以下两种情景&#xff1a; 由于文件过大&#xff0c;直接向组员分享文件2很麻烦。由于修改地方过多&#xff0c;每次更换环境都需要重新修改文…

【JAVA语言-第18话】集合框架(五)——Map、HashMap、LinkedHashMap、TreeMap集合

目录 双列集合Map 1.1 概述 1.2 特点 1.3 Map接口中的常用方法 1.3.1 练习 1.4 HashMap集合 1.4.1 概述 1.4.2 特点 1.5 LinkedHashMap集合 1.5.1 概述 1.5.2 特点 1.6 TreeMap集合 1.6.1 概述 1.6.2 特点 1.7 Map集合练习 1.8 HashMap、LinkedHashMap、Tre…

【EI会议征稿通知】第五届城市工程与管理科学国际会议(ICUEMS 2024)

【Scopus稳定检索】第五届城市工程与管理科学国际会议&#xff08;ICUEMS 2024&#xff09; 2024 5th International Conference on Urban Engineering and Management Science 第五届城市工程与管理科学国际会议&#xff08;ICUEMS 2024&#xff09;将于2024年5月31日-6月2日…

GitKraken Create Repository and Clone不可点击

问题 GitKraken Create Repository and Clone不可点击 详细问题 笔者第一次使用GitKraken&#xff0c;在创建仓库时&#xff0c;填写完成仓库初始化后。发现Create Repository and Clone不可点击。 解决方案 选择Where to clone to位置 产生原因 在创建仓库时&#xff0…

洛谷: P1479 宿舍里的故事之五子棋

题目链接: https://www.luogu.com.cn/problem/P1479 思路: 这道题目可以打表或者搜索。每个位置有选择/不选择两种情况。搜索的时候我们一行一行的搜索&#xff0c;直到使用的棋子达到n为止。b[i]为五子连线的数量&#xff0c;b[i] 1表示五子连线的数量可以取i&#xff0c;在…

day6:继承与多态

思维导图 2.编程题&#xff1a; 以下是一个简单的比喻&#xff0c;将多态概念与生活中的实际情况相联系&#xff1a;比喻&#xff1a;动物园的讲解员和动物表演 想象一下你去了一家动物园&#xff0c;看到了许多不同种类的动物&#xff0c;如狮子、大象、猴子等。现在&#xff…

如何引导llm为自己写prompt生成剧本

如何使用写prompt让你自己生一个狗血修仙穿越短剧&#xff0c;且短剧有趣生动让人流连忘返 好的&#xff0c;我会尝试编写一个狗血修仙穿越短剧的prompt&#xff0c;以激发你的想象力&#xff0c;让你创作出一个既有趣又生动的短剧。以下是我的prompt&#xff1a; 标题&#x…

简洁高效的短链接:优化互联网体验

title: 简洁高效的短链接&#xff1a;优化互联网体验 date: 2024/2/18 13:24:24 updated: 2024/2/18 13:24:24 tags: 短链接长网址缩短美观简洁分享优化点击率提升数据统计用户体验 在互联网时代&#xff0c;我们经常遇到需要分享长网址的情况。长网址不仅不美观&#xff0c;而…

Mysql开启bin-log日志

目录 一、安装配置 二、mysqlbinlog命令 一、安装配置 yum -y install mariadb mariadb-server#安装mysql数据库#默认配置文件/etc/my.cnfvim /etc/my.cnflog-binmariadb-bin #开启二进制日志 systemctl restart mariadb#会在/car/lib/mysql/产生二进制日志文件&#xff0…

防火墙(三) -----------------关于iptables规则的保存

一、关于iptables规则的保存 之前写的iptables的设置&#xff0c;但是都是临时生效的&#xff0c;一旦电脑重启&#xff0c;那么就会失效&#xff0c;如何永久保存&#xff0c;需要借助iptables-save命令&#xff0c;开机生效需要借助iptables-restore命令&#xff0c;并写入规…

AB测试最小样本量

1.AB实验过程 常见的AB实验过程&#xff0c;分流-->实验-->数据分析-->决策&#xff1a;分流&#xff1a;用户被随机均匀的分为不同的组实验&#xff1a;同一组内的用户在实验期间使用相同的策略&#xff0c;不同组的用户使用相同或不同的策略。数据收集&#xff1a;…

HOOPS发布全新CAD文件支持以及改进的API性能版本!增加了对Navisworks和C#支持!

全球工程软件开发工具包的领先提供商Tech Soft 3D今天宣布推出HOOPS Exchange 2024&#xff08;支持30多种文件格式的领先CAD数据转换SDK&#xff09;和HOOPS Publish 2024&#xff0c;用于发布交互式3D PDF、3D HTML和3D CAD数据的领先工具包。 HOOPS Exchange现在支持Navisw…

C++day6

模拟跟随导演去动物园&#xff1a; #include <iostream>using namespace std; class Animal { private:string name; public:Animal(){}Animal(string name):name(name){}virtual void perform(){cout << name << "为我们讲解,说&#xff1a;" &…

php 数组函数

php 数组函数 1. 常用的php数组函数 1. 常用的php数组函数 array_pop() 删除数组中最后一个元素 array_push() 将一个或多个元素插入到数组的末尾 array_keys <?php $arr array("刘岩" > 30, "范冰冰" > 31, "娜扎" > 31);$…

~汉诺塔~(C语言)~

引言 汉诺塔&#xff08;Hanoi Tower&#xff09;&#xff0c;又称河内塔&#xff0c;源于印度一个古老传说。大梵天创造世界的时候做了三根金刚石柱子&#xff0c;在一根柱子上从下往上按照大小顺序摞着64片黄金圆盘。大梵天命令婆罗门把圆盘从上面开始按大小顺序重新摆放在…