C++之boost智能指针

1、boost智能指针

资源获取即初始化:在构造函数中对资源进行初始化,在析构函数中释放。

智能指针的本质思想是:将堆对象的生存期,用栈对象来管理。这个栈对象就是智能指针。

当new 一个堆对象的时候,立刻用智能指针来接管,

具体做法是:在构造函数进行初始化(用一个指针指向堆对象),在析构函数中调用delete来释放堆对象。

由于智能指针本身是一个栈对象,它的作用域结束的时候,自动调用析构函数,从而调用了delete释放了堆对象。

2、scoped_ptr<T>

#include <iostream>
#include <boost/smart_ptr.hpp>
using namespace std;class X
{
public:X(){cout << "X ..." << endl;}~X(){cout << "~X ..." << endl;}
};int main() {cout << "entering main ..." << endl;{// 将p放在这个{}中,出了这个{},作用域就消失了boost::scoped_ptr<X> p(new X);// 既不能被拷贝,也不能被赋值(下面这样编译报错,因为在scoped_ptr里里面,拷贝构造和=运算符都是声明成私有的)// boost::scoped_ptr<X> p(p);}std::cout << "Hello, World!" << std::endl;return 0;
}// 输出
entering main ...
X ...
~X ...
Hello, World!

3、share_ptr<T>

如果我们都不调用reset的话,当p1和p2这两个栈上的变量也会自动销毁,销毁的时候也会自动去调用reset。

为什么说shared_ptr是线程安全的?因为在做加法的时候,是一个原子操作BOOST_INTERLOCKED_INCREMENT。

#include <iostream>
#include <boost/smart_ptr.hpp>
#include <boost/shared_ptr.hpp>
using namespace std;class X
{
public:X(){cout << "X ..." << endl;}~X(){cout << "~X ..." << endl;}
};int main() {cout << "entering main ..." << endl;boost::shared_ptr<X> p1(new X);cout << p1.use_count() << endl;boost::shared_ptr<X> p2(p1);cout << p2.use_count() << endl;boost::shared_ptr<X> p3;p3 = p1;cout << p2.use_count() << endl;p1.reset();cout << p2.use_count() << endl;p2.reset();cout << p2.use_count() << endl;std::cout << "exiting main ..." << std::endl;return 0;
}// 输出
entering main ...
X ...
1
2
3
2
0
exiting main ...
~X ...

share_ptr<T>注意事项

循环引用(这样的情况下,销毁的时候内部放入引用还都是1,所以不会调用析构函数)

解决方案:手动将引用减一

#include <iostream>
#include <boost/smart_ptr.hpp>
#include <boost/shared_ptr.hpp>
using namespace std;class Child;
class Parent;
typedef boost::shared_ptr<Parent> parent_ptr;
typedef boost::shared_ptr<Child> child_ptr;class Child
{
public:Child(){cout << "Child ..." << endl;}~Child(){cout << "~Child ..." << endl;}parent_ptr parent_;
};class Parent
{
public:Parent(){cout << "Parent ..." << endl;}~Parent(){cout << "~Parent ..." << endl;}child_ptr child_;
};int main() {parent_ptr parent(new Parent);child_ptr child(new Child);parent->child_ = child;child->parent_ = parent;parent->child_.reset();return 0;
}// 输出
Parent ...
Child ...
~Child ...
~Parent ...

还有一种解决方式,是通过weak_ptr来解决。

4、weak_ptr<T>

#include <iostream>
#include <boost/smart_ptr.hpp>
#include <boost/shared_ptr.hpp>
using namespace std;class Child;
class Parent;
typedef boost::shared_ptr<Parent> parent_ptr;
typedef boost::shared_ptr<Child> child_ptr;class Child
{
public:Child(){cout << "Child ..." << endl;}~Child(){cout << "~Child ..." << endl;}parent_ptr parent_;
};class Parent
{
public:Parent(){cout << "Parent ..." << endl;}~Parent(){cout << "~Parent ..." << endl;}//child_ptr child_;boost::weak_ptr<Child> child_;
};int main() {parent_ptr parent(new Parent);  // 1child_ptr child(new Child);     // 1parent->child_ = child;            // 1child->parent_ = parent;           // 2//    parent->child_.reset();return 0;
}// 输出
Parent ...
Child ...
~Child ...
~Parent ...

通过weak_ptr访问成员的时候,要提升到share_ptr

#include <iostream>
#include <boost/smart_ptr.hpp>
#include <boost/shared_ptr.hpp>
using namespace std;class X
{
public:X(){cout << "X ..." << endl;}~X(){cout << "~X ..." << endl;}void Fun(){cout << "Fun ..." << endl;}
};int main() {boost::weak_ptr<X> p;{boost::shared_ptr<X> p2(new X);cout << p2.use_count() << endl;p = p2;cout << p2.use_count() << endl;boost::shared_ptr<X> p3 = p.lock();  // lock()表示提升为shared_ptrif (!p3){cout << "object is destroyed " << endl;}else{p3->Fun();}}boost::shared_ptr<X> p4 = p.lock();if(!p4){cout << "object is destroyed " << endl;}else{p4->Fun();}return 0;
}
// 输出
X ...
1
1
Fun ...
~X ...
object is destroyed

5、PIMPL

问题原因:嵌套了多重头文件,编译速度降低;因为类Y中有X的对象,这样如果X类改变,所有Y的对象都需要重新编译,因为此时类Y的大小已经改变,这样客户程序就不仅仅依赖于接口,还依赖于库里面的具体实现。

解决方法:将包含头文件改成声明类;将对象改成指针(32位的4个字节,64位8个字节,这是不会变化的)

如果一定要使用到类的对象的话,那就把类的对象都抽象到同一个类Impl中,然后通过Impl的指针来访问

class Y
{Impl P;
};class Impl
{A a;B b;C c;
};

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

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

相关文章

AI免费文档处理在线工具:文档总结;论文阅读

1、文档总结 NoteGPT 支持各种类型文档ppt、word、pdf等总结 https://notegpt.io/pdf-summary 另外各种大模型工具一般都支持文档上传总结&#xff1a; 例如kimi、通义等 参考&#xff1a;https://blog.csdn.net/weixin_42357472/article/details/138205261 2、论文阅读 h…

plugin:vite:import-analysis]No known conditions for“./lib/locale/lang/zh-cn“

将原有引入&#xff1a; import zhCn from element-plus/lib/locale/lang/zh-cn 改成&#xff1a; import zhCn from element-plus/es/locale/lang/zh-cn; 原因版本升级&#xff0c;引入路径改变&#xff08;原先的包在node_modules\element-plus\lib找不到&#xff09; 新…

c++习题09-分离整数的各个数

目录 一&#xff0c;题目 二&#xff0c;思路 三&#xff0c;代码 一&#xff0c;题目 二&#xff0c;思路 一开始我想到的是将简单容易输出的1000以内的数先进行相应的运算&#xff0c;再输出之后再对1000以上的数字进行判断&#xff08;主要还是想先将很大的数变小&#x…

如何自动筛选螺丝不良品?

四角螺丝是一种特殊设计的螺丝&#xff0c;其螺纹头部呈四个平行的角状结构&#xff0c;与传统的六角螺丝相比具有独特的外观和功能。这种设计使得四角螺丝在安装和拆卸时更容易使用&#xff0c;并提供了更好的扭矩传递效率。四角螺丝头部呈现四个平行的角&#xff0c;与常见的…

如何通过IP地址查询地理位置及运营商信息

在数字时代&#xff0c;IP地址&#xff08;Internet Protocol Address&#xff0c;互联网协议地址&#xff09;已经成为我们日常网络活动的重要组成部分。每台连接到互联网的设备都被分配了一个唯一的IP地址&#xff0c;它不仅可以识别设备&#xff0c;还可以揭示设备的地理位置…

图像信号处理器(ISP)基础算法及处理流程

&#x1f4aa; 专业从事且热爱图像处理&#xff0c;图像处理专栏更新如下&#x1f447;&#xff1a; &#x1f4dd;《图像去噪》 &#x1f4dd;《超分辨率重建》 &#x1f4dd;《语义分割》 &#x1f4dd;《风格迁移》 &#x1f4dd;《目标检测》 &#x1f4dd;《暗光增强》 &a…

传输距离3000M|低延迟|48K采样音频传输模块-SA356大功率发射模块

无线音频应用中&#xff0c;远距离音频传输在许多领域具有广泛的应用需求&#xff0c;例如大型会议系统、公共广播、户外活动和音乐演出等。为了满足这些需求&#xff0c;音频传输模块需要具备一些关键特性&#xff0c;包括长距离传输能力、高音质、低延迟、稳定性以及抗干扰能…

fastzdp_login的第一次构建

概述 为了方便能够快捷的实现fastapi实现登录相关功能代码开发&#xff0c;决定开发一个开源的fastapi组件库&#xff0c;想了很多个名字&#xff0c;在检查pypi的时候发现都被占用了&#xff0c;所以最终决定使用fastzdp_login这个名字。 fast代表的时fastapi。zdp代表的是张…

Springboot与xxl-job

一、下载xxl-job项目 XXL-JOB是一个分布式任务调度平台&#xff0c;其核心设计目标是开发迅速、学习简单、轻量级、易扩展。现已开放源代码并接入多家公司线上产品线&#xff0c;开箱即用。 从GitHub上面将项目clone下来&#xff0c;如果网络问题导致速度慢也可以从Gitee上面拉…

JavaScript中的立即执行函数表达式(Immediately Invoked Function Expression, IIFE)

聚沙成塔每天进步一点点 本文回顾 ⭐ 专栏简介JavaScript中的立即执行函数表达式&#xff08;Immediately Invoked Function Expression, IIFE&#xff09;1. 引言2. IIFE的概念2.1 概述2.2 语法2.3 历史背景 3. IIFE的作用3.1 创建独立作用域3.2 模块化代码3.3 防止变量提升3.…

SAPUI5基础知识10 - i18与国际化

1. 背景 i18n 是 “internationalization” 的缩写&#xff0c;其中的 18 是 “internationalization” 这个单词中间的字符数。i18n 是一种让应用程序支持多种语言的方法&#xff0c;也就是我们通常所说的国际化。 在SAPUI5中&#xff0c;i18n主要通过使用资源模型&#xff…

跑腿平台小程序的设计

管理员账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;基础数据管理&#xff0c;管理员管理&#xff0c;接单详情管理&#xff0c;跑腿员管理&#xff0c;跑腿任务管理 微信端账号功能包括&#xff1a;系统首页&#xff0c;跑腿任务&#xff0c;接单员&…

RocketMQ源码学习笔记:Producer启动流程

这是本人学习的总结&#xff0c;主要学习资料如下 马士兵教育rocketMq官方文档 目录 1、Overview1.1、创建MQClientInstance1.1.1、检查1.1.1、MQClientInstance的ID 1.2、MQClientInstance.start() 1、Overview 这是发送信息的代码样例&#xff0c; DefaultMQProducer produ…

Gradio 教程四:Building Generative AI Applications with Gradio

文章目录 一、使用interface构建NLP应用1.1 构建文本摘要应用1.1.1 设置API密钥1.1.2 调用文本摘要API1.1.3 运行本地模型获取响应1.1.4 使用interface构建应用 1.2 构建命名实体识别应用1.2.1 调用NER任务API1.2.2 使用interface构建应用1.2.3 加入额外函数&#xff0c;合并to…

CPU/内存/综合性能评估工具汇总-3:unixbench

目录 一、概括二、UnixBench 一、概括 嵌入式开发中对要设计的产品、立项的项目进行设计时&#xff0c;往往需要对关键芯片进行性能评估&#xff0c;本文主要总结基于linux系统的产品在性能评估时的工具使用总结&#xff0c;在aarch64(arm64平台下测试)&#xff0c;板卡根文件…

Rhino 犀牛三维建模工具下载安装,Rhino 适用于机械设计广泛领域

Rhinoceros&#xff0c;这款软件小巧而强大&#xff0c;无论是机械设计、科学工业还是三维动画等多元化领域&#xff0c;它都能展现出其惊人的建模能力。 Rhinoceros所包含的NURBS建模功能&#xff0c;堪称业界翘楚。NURBS&#xff0c;即非均匀有理B样条&#xff0c;是计算机图…

【笔记】记录一次全新的Java项目部署过程

记录一次全新的Java项目部署过程 环境&#xff1a;CentOS7 一、初始环境准备 yum install wget -y yum install vim -y yum install net-tools -y mkdir /data mkdir /data/html mkdir /data/backend一、安装JDK 17 安装JDK17 # 下载rpm wget https://download.oracle.com…

数据驱动:Facebook的广告策略与商业模式

在现代数字经济中&#xff0c;数据已经成为新的石油&#xff0c;驱动着企业的增长和创新。Facebook&#xff0c;作为全球最大的社交媒体平台之一&#xff0c;充分利用其庞大的用户数据和先进的算法技术&#xff0c;建立了一个高度精确和高效的广告生态系统。这不仅推动了平台自…

带着味蕾去旅行,在“必吃”餐厅里认识一座城

时代不同了&#xff0c;旅游也变了。十多年前的旅游&#xff0c;是文艺青年的诗与远方&#xff0c;生活在别处的荷尔蒙之旅&#xff0c;宁浩拍了部电影叫《心花怒放》&#xff0c;那些年不管是大理、丽江、拉萨、成都&#xff0c;还是张家界&#xff0c;商家最喜欢用的宣传口号…

Oracle Database 23ai新特性:DB_DEVELOPER_ROLE角色

角色介绍 从 Oracle Database 23ai 开始&#xff0c;新角色“DB_DEVELOPER_ROLE”允许管理员快速分配开发人员为 Oracle 数据库设计、构建和部署应用程序所需的所有必要权限。&#xff08;包括构建数据模型所需的系统权限以及监视和调试应用程序所需的对象权限&#xff09;。通…