C++11:智能指针(二)实战篇(附上实例)

目录

1、unique_ptr:

2、shared_ptr:

3、weak_ptr:

4、如何处理循环引用问题?


C++智能指针是一种用于管理动态分配的对象的指针,它可以自动释放所指向的对象,避免内存泄漏和悬空指针的问题。

C++标准库提供了三种智能指针:unique_ptr、shared_ptr和weak_ptr。

智能指针的基本知识可以看上一篇文章:C++11:智能指针(一)_智能指针c++11_Ivy_belief的博客-CSDN博客

1、unique_ptr:

unique_ptr是独占所有权的智能指针,它保证只有一个指针可以指向该对象。当unique_ptr超出作用域或被显式地释放时,它会自动删除所指向的对象。

std::unique_ptr<int> ptr(new int(10));
// 使用ptr指向的对象*ptr = 20;
// 不需要手动释放内存,unique_ptr会在超出作用域时自动释放

2、shared_ptr:

shared_ptr是共享所有权的智能指针,它可以被多个指针同时指向同一个对象。它使用引用计数来追踪对象的引用数量,并在引用计数为0时自动删除所指向的对象。

std::shared_ptr<int> ptr1(new int(10));
std::shared_ptr<int> ptr2 = ptr1;  // 多个指针指向同一个对象// 使用ptr1或ptr2指向的对象*ptr1 = 20;
*ptr2 = 30;
// 不需要手动释放内存,shared_ptr会在引用计数为0时自动释放

3、weak_ptr:

weak_ptr是一种弱引用的智能指针,它指向shared_ptr所管理的对象,但不会增加引用计数。weak_ptr可以用于解决shared_ptr循环引用的问题。

std::shared_ptr<int> ptr1(new int(10));
std::weak_ptr<int> ptr2 = ptr1;  // 弱引用指向ptr1所指向的对象// 使用ptr1或ptr2指向的对象*ptr1 = 20;
// 不需要手动释放内存,当所有shared_ptr释放后,weak_ptr无效

智能指针的使用可以简化内存管理,避免手动释放内存和悬空指针的问题。根据具体的需求,选择合适的智能指针来管理动态分配的对象,以提高代码的安全性和可维护性。

4、如何处理循环引用问题?

(1)如何处理循环引用问题取决于你使用的智能指针类型。

        当两个或多个对象相互引用时,可能会形成循环引用,导致内存泄漏,因为它们的引用计数永远不会达到0。

(2)一种常见的解决方案是使用weak_ptr来打破循环引用

        weak_ptr是一种弱引用的智能指针,它不会增加引用计数。在存在循环引用的情况下,可以将其中一个shared_ptr替换为weak_ptr,这样就不会导致引用计数无法减少。

(3)代码示例:

class B;  // 前向声明class A 
{
public:std::shared_ptr<B> bPtr;
};class B 
{
public:std::weak_ptr<A> aWeakPtr;
};std::shared_ptr<A> aPtr(new A());
std::shared_ptr<B> bPtr(new B());aPtr->bPtr = bPtr;
bPtr->aWeakPtr = aPtr;

在上面的示例中,A类和B类相互引用。为了避免循环引用,A类中的bPtr使用shared_ptr,而B类中的aWeakPtr使用weak_ptr。

通过使用weak_ptr,当所有shared_ptr释放后,循环引用中的对象会被正确地销毁,从而避免了内存泄漏。

需要注意的是,在使用weak_ptr时,需要检查weak_ptr是否有效(expired)才能访问所指向的对象,可以使用lock()方法来获取一个有效的shared_ptr。


std::shared_ptr<A> aPtr = bPtr->aWeakPtr.lock();
if (aPtr) 
{// weak_ptr有效,可以访问aPtr所指向的对象
} 
else 
{// weak_ptr无效,aPtr已经被销毁
}

这样,你就可以通过使用weak_ptr来解决循环引用问题,并确保内存正确释放。

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

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

相关文章

Redis的优势

高性能 Redis是一种基于内存的数据存储系统&#xff0c;读写性能非常高&#xff0c;因此适用于对性能要求较高的应用场景。 数据结构丰富 Redis支持多种数据结构&#xff0c;如字符串、列表、集合、散列、有序集合等&#xff0c;可以满足不同的业务需求。还有一些特殊数据结…

Linux流量监控

yum install -y iptrafiptraf-ng -d ens33

关于近期IP-Guard新版本客户端重复发送邮件的问题处理说明

关于近期新版本客户端重复发送邮件的问题处理说明 一、问题描述 近期部分客户反馈,升级到新版本的客户端(4.81.341.0、4.82.621.0及以上),使用SMTP协议发送邮件时,会出现重复发送邮件的情况,主要表现为以下两种现象: Outlook发送包含大量收件人的邮件时,收件人邮箱可能…

11 结构型模式- 代理模式

结构性模式一共包括七种&#xff1a; 代理模式、桥接模式、装饰者模式、适配器模式、门面(外观)模式、组合模式、和享元模式。 1 代理模式介绍 软件开发中的代理&#xff1a; 代理模式中引入了一个新的代理对象,代理对象在客户端对象和目标对象之间起到了中介的作用,它去掉客…

LSTM 与 GRU

RNN无法处理长距离依赖问题&#xff0c;通俗点就是不能处理一些较长的序列数据&#xff0c;那么今天就来介绍一下两个能处理长距离依赖问题地RNN变种结构&#xff0c;LSTM和GRU。 1. LSTM&#xff08;Long short-term memory&#xff09; 1.1 LSTM结构 上左图是普通RNN结构图…

Windows下Eclipse C/C++开发环境配置教程

1.下载安装Eclipse 官网下载eclipse-installer&#xff08;eclipse下载器&#xff09;&#xff0c;或者官方下载对应版本zip。 本文示例&#xff1a; Eclipse IDE for C/C Developers Eclipse Packages | The Eclipse Foundation - home to a global community, the Eclipse ID…

#Day Day Plan# 《NCB_PCI_Express_Base 5.0.1.0》pdf 译文笔记

目录 前言碎语 第4章 Physical Layer Logic Block S4.1 Introduction S4.2 Logical sub-block S4.2.4 Link Initialization and Traning S4.2.4.3 Electrical Idle Sequence(EIOS) 译文&#xff1a;EIOS 电器空闲Ordered Set S4.2.7 Link Training and Status State R…

C语言-面试题实现有序序列合并

要求&#xff1a; a.输入两个升序排列的序列&#xff0c;将两个序列合并为一个有序序列并输出。 数据范围&#xff1a; 1≤n,m≤1000 1≤n,m≤1000 &#xff0c; 序列中的值满足 0≤val≤30000 输入描述&#xff1a; 1.输入包含三行&#xff0c; 2.第一行包含两个正整数n, m&am…

【强连通+背包】CF1763E

Problem - E - Codeforces 题意 思路 首先&#xff0c;先考虑第一个条件&#xff0c;要保证是p个节点互相到达且节点数最少&#xff0c;一定是个强连通&#xff0c;图的形态一定就是和强连通相关的。 然后&#xff0c;因为在这个前提上&#xff0c;要让单向节点数尽可能多&a…

【密评】商用密码应用安全性评估从业人员考核题库(十一)

商用密码应用安全性评估从业人员考核题库&#xff08;十一&#xff09; 国密局给的参考题库5000道只是基础题&#xff0c;后续更新完5000还会继续更其他高质量题库&#xff0c;持续学习&#xff0c;共同进步。 2501 多项选择题 GM/T 0047《安全电子签章密码检测规范》规定的电…

shell 中单引号,双引号,反引号的区别

1 单引号 str1hello echo $str1 打印结果是&#xff1a;$str1 总结&#xff1a; 单引号里的任何字符都会原样输出&#xff0c;单引号字符串中的变量是无效的&#xff0c;所以不能使用单引号 来解析变量。不过单引号可以引用变量。 例如&#xff1a; str1hello echo $str…

IMU预积分的过程详解

一、IMU和相机数据融合保证位姿的有效性&#xff1a; 当运动过快时&#xff0c;相机会出现运动模糊&#xff0c;或者两帧之间重叠区域太少以至于无法进行特征匹配&#xff0c;所以纯视觉SLAM对快速的运动很敏感。而有了IMU&#xff0c;即使在相机数据无效的那段时间内&#xff…

iOS UIWebView与WKWebView 那些事

一、前言介绍 UIWebView 是 iOS 2 中推出的网页容器,UIWebView是最占内存的控件;直到 iOS 8 以后,苹果推出了 WebKit 框架,其中 WKWebView 正式被推出来接替 UIWebView 的位置;iOS 12 中,苹果正式弃用 UIWebView,要求开发者用 WKWebView 全面替换 UIWebView,apple 官方…

C++ -- 位运算与常用库函数(ACWING语法基础)

位运算 & 与 | 或 ~ 非 ^ 异或 >> 右移 << 左移 常用操作&#xff1a; 求x的第k位数字 x >> k & 1lowbit(x) x & -x&#xff0c;返回x的最后一位1 常用库函数、 reverse 翻转 翻转一个vector&#xff1a; reverse(a.begin(), a.end(…

C++基类和派生类的内存分配,多态的实现

目录 基类和派生类的内存分配基类和派生类的成员归属多态的实现 基类和派生类的内存分配 类包括成员变量&#xff08;data member&#xff09;和成员函数&#xff08;member function&#xff09;。 成员变量分为静态数据&#xff08;static data&#xff09;和非静态数据&…

html web前端,登录,post请求提交 json带参

html web前端&#xff0c;登录&#xff0c;post请求提交 json带参 3ca9855b3fd279fa17d46f01dc652030.jpg <!DOCTYPE html> <html><head><meta http-equiv"Content-Type" content"text/html; charsetutf-8" /><title></t…

FPGA【紫光语法】

寄存器数据类型&#xff1a; reg 默认为 1 bit wide&#xff0c;如果超过 1 bit&#xff0c;则需要 range declaration 设置 reg 的位宽integer 默认位宽为 32 bit&#xff0c;不允许有 range declarationtime 默认位宽为 64 bit&#xff0c;不允许有 range declarat…

sqlmap 攻击

sqlmap 是kali 里面的工具 sqlmap对注入点注入 1 如果是 get 注入&#xff0c;直接&#xff0c;sqlmap -u "注入点网址". 2 如果是 post 注入&#xff0c;可以 sqlmap –r "burp 地址访问包” 3 如果是 cookie&#xff0c;X-Forwarded-For 等&#xff0c…

02-2、PyCharm中文乱码的三处解决方法

PyCharm中文乱码 修改处1&#xff1a; 修改处2&#xff1a;这个也没用 在Pycharm中可以创建一个模版&#xff0c;每次新建python文件时Pycharm会默认在前两行生成utf-8 #!/user/bin/env python3 # -- coding: utf-8 -- 还是乱码 再在这里设置以下 添加 &#xff1a; -Dfi…

坐标由本地坐标系转wgs84坐标系

&#xff08;1&#xff09;坐标系一&#xff1a;&#xff08;0,0,0&#xff09;为原点的本地坐标系 &#xff08;2&#xff09;坐标系二&#xff1a;wgs84坐标系 转换方法&#xff1a;proj4 关键点&#xff1a;需要知道&#xff08;0,0,0&#xff09;原点的经纬度坐标 代码&a…