关于智能指针

实现自己的智能指针

//智能指针 保证能做到资源的自动释放
//利用栈上的对象出作用域自动析构的特征,来做到资源的自动释放的
template<typename T>
class CSmartPtr
{
public:CSmartPtr(T *ptr = nullptr):mptr(ptr) {}~CSmartPtr() { delete mptr; }
private:T *mptr;
};int main()
{CSmartPtr<int> ptr1(new int);return 0;
}

不能把智能指针new在堆上

CSmartPtr<int> *p = new CSmartPtr<int>(new int); //p还是裸指针

重载*->

//智能指针 保证能做到资源的自动释放
//利用栈上的对象出作用域自动析构的特征,来做到资源的自动释放的
template<typename T>
class CSmartPtr
{
public:CSmartPtr(T *ptr = nullptr):mptr(ptr) {}~CSmartPtr() { delete mptr; }T& operator*() { return *mptr; }T* operator->() { return mptr; }
private:T *mptr;
};int main()
{CSmartPtr<int> ptr1(new int);class Test{public:void test() { cout << "Test::test()" << endl; }};CSmartPtr<Test> test(new Test());test->test();return 0;
}
	/*不带引用计数的智能指针auto_ptr:C++库里面C++11新标准:scoped_ptrunique_ptr*/auto_ptr<int> ptr1(new int);auto_ptr<int> ptr2(ptr1);*ptr2 = 20;cout << *ptr1 << endl; //ptr1现在为空//不推荐使用auto_ptr//scoped_ptr
//scoped_ptr(const scoped_ptr<T>&) = delete;
//scoped_ptr<T>& operator=(const scoped_ptr<T>&) = delete;unique_ptrunique_ptr(const unique_ptr<T>&) = delete;unique_ptr<T>& operator=(const unique_ptr<T>&) = delete;//实现了右值引用的拷贝unique_ptr(unique_ptr<T> &&src)unique_ptr<T>& operator=(unique_ptr<T> &&src)template<typename T>unique_ptr<T> getSmartPtr(){unique_ptr<T> ptr(new T());return ptr;}unique_ptr<int> ptr1 = getSmartPtr<int>();unique_ptr<int> p1(new int);unique_ptr<int> p2(std::move(p1));

引用计数

//对资源进行引用计数的类
template<typename T>
class RefCnt
{
public:RefCnt(T *ptr = nullptr):mptr(ptr){if (mptr != nullptr)mcount = 1;}//增加资源的引用计数void addRef(){mcount++;}int delRef() { return --mcount; }
private:T *mptr;int mcount;
};//智能指针 保证能做到资源的自动释放
//利用栈上的对象出作用域自动析构的特征,来做到资源的自动释放的
template<typename T>
class CSmartPtr
{
public:CSmartPtr(T *ptr = nullptr):mptr(ptr) {mpRefCnt = new RefCnt<T>(mptr);}~CSmartPtr() { if (0 == mpRefCnt->delRef()){delete mptr; mptr = nullptr;}}T& operator*() { return *mptr; }T* operator->() { return mptr; }CSmartPtr(const CSmartPtr<T> &src):mptr(src.mptr), mpRefCnt(src.mpRefCnt){if (mptr != nullptr)mpRefCnt->addRef();}CSmartPtr<T>& operator=(const CSmartPtr<T> &src){if (this == &src)return *this;if (0 == mpRefCnt->delRef()){delete mptr;}mptr = src.mptr;mpRefCnt = src.mpRefCnt;mpRefCnt->addRef();return *this;}
private:T *mptr; //指向资源的指针RefCnt<T> *mpRefCnt; //指向该资源引用计数对象的指针
};
int main()
{CSmartPtr<int> ptr1(new int);CSmartPtr<int> ptr2(ptr1);CSmartPtr<int> ptr3;ptr3 = ptr2;*ptr1 = 20;cout << *ptr2 << " " << *ptr3 << endl;return 0;
}

循环引用

class B;
class A
{
public:A() { cout << "A()" << endl; }~A() { cout << "~A()" << endl; }shared_ptr<B> _ptrb;
};class B
{
public:B() { cout << "B()" << endl; }~B() { cout << "~B()" << endl; }shared_ptr<A> _ptra;
};int main()
{shared_ptr<A> pa(new A());shared_ptr<B> pb(new B());pa->_ptrb = pb;pb->_ptra = pa;cout << pa.use_count() << endl;cout << pb.use_count() << endl;return 0;
}

定义对象的时候,用强智能指针;引用对象的地方,使用弱智能指针

class B;
class A
{
public:A() { cout << "A()" << endl; }~A() { cout << "~A()" << endl; }weak_ptr<B> _ptrb;
};class B
{
public:B() { cout << "B()" << endl; }~B() { cout << "~B()" << endl; }weak_ptr<A> _ptra;
};int main()
{shared_ptr<A> pa(new A());shared_ptr<B> pb(new B());pa->_ptrb = pb;pb->_ptra = pa;cout << pa.use_count() << endl;cout << pb.use_count() << endl;return 0;
}

weak_ptr只是观察作用,观察资源还可不可用,但是却不能用

class B;
class A
{
public:A() { cout << "A()" << endl; }~A() { cout << "~A()" << endl; }void testA() { cout << "非常好用的方法" << endl; }weak_ptr<B> _ptrb;
};class B
{
public:B() { cout << "B()" << endl; }~B() { cout << "~B()" << endl; }void func(){_ptra->testA();//使用不了}weak_ptr<A> _ptra;
};

在使用时必须进行提升

class B
{
public:B() { cout << "B()" << endl; }~B() { cout << "~B()" << endl; }void func(){//_ptra->testA();//使用不了shared_ptr<A> ps = _ptra.lock(); //提升方法if (ps != nullptr){ps->testA();}}weak_ptr<A> _ptra;
};
//多线程访问共享对象的线程安全问题
class A
{
public:A() { cout << "A()" << endl; }~A() { cout << "~A()" << endl; }void testA() { cout << "非常好用的方法!" << endl; }
};void handler01(A *q)
{std::this_thread::sleep_for(std::chrono::seconds(2));//q访问A对象的时候,需要侦测一下A对象是否存活q->testA();
}int main()
{A *p = new A();thread t1(handler01, p);delete p;t1.join();return 0;
}
class A
{
public:A() { cout << "A()" << endl; }~A() { cout << "~A()" << endl; }void testA() { cout << "非常好用的方法!" << endl; }
};void handler01(weak_ptr<A> pw)
{std::this_thread::sleep_for(std::chrono::seconds(2));shared_ptr<A> sp = pw.lock();if (sp != nullptr){sp->testA();}else{cout << "A对象已经析构,不能访问" << endl;}
}int main()
{{shared_ptr<A> p(new A());thread t1(handler01, weak_ptr<A>(p));t1.detach();}std::this_thread::sleep_for(std::chrono::seconds(20));return 0;
}
/*
智能指针的删除器 deletor
智能指针:能够保证资源绝对的释放
*/
//unique_ptr shared_ptr
/*
~unique_ptr() {是一个函数对象的调用 deletor(ptr); }
template<typename T>
class Deletor
{
public:void operator()(T *ptr){delete ptr;}
};
*/template<typename T>
class MyDeletor
{
public:void operator()(T *ptr) const{cout << "call MyDeletor.operator()" << endl;delete []ptr;}
};int main()
{unique_ptr<int, MyDeletor<int>> ptr1(new int[100]);return 0;
}
template<typename T>
class MyFileDeletor
{
public:void operator()(T *ptr) const{cout << "call MyFileDeletor.operator()" << endl;fclose(ptr);}
};int main()
{unique_ptr<FILE, MyFileDeletor<FILE>> ptr(fopen("data.txt", "w"));return 0;
}

使用lambda

	unique_ptr<int, function<void(int*)>> ptr1(new int[100],[](int *p)->void {cout << "call lambda release new int[100]" << endl;delete[]p;});unique_ptr<FILE, function<void(FILE*)>> ptr2(fopen("data.txt", "w"),[](FILE *p)->void {cout << "call lambda release fopen" << endl;fclose(p);});

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

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

相关文章

Spring实现事务(一)

Spring事务 .什么是事务事务的操作Spring中事务的实现准备工作创建表创建项目,引入Spring Web, Mybatis, mysql等依赖配置文件实体类 编程式事务(手动写代码操作事务)声明式事务(利用注解自动开启和提交事务) . 什么是事务 事务是⼀组操作的集合, 是⼀个不可分割的操作 在我们…

国产校准件

国产校准件 Ceyear系列校准件是矢量网络分析仪的测试附件&#xff0c;可大幅提高矢量网络分析仪的测试精度。规格品种丰富&#xff0c;涵盖多种同轴、波导校准件&#xff0c;校准精度高&#xff0c;重复性好 功能特点 校准件 校准模块可实现更精准的测量&#xff0c;满足您的测…

RK3588平台开发系列讲解(视频篇)H.264码流结构介绍

文章目录 一、 码流查看工具二、 I帧、 P帧、 B帧三、序列四、GOP, 即关键帧间隔五、片和宏块沉淀、分享、成长,让自己和他人都能有所收获!😄 📢H.264码流结构介绍。 一、 码流查看工具 ① H.264码流查看工具: Elecard_streamEye、 Elecard StreamEye Tools、 Special…

020 switch多选择结构

什么是switch多选择结构 switch语句中的变量类型为char的示例 char grade A; switch (grade){case A:System.out.println("成绩为A");break;case B:System.out.println("成绩为B");break;case C:System.out.println("成绩为C");break;case D:S…

2. HarmonyOS应用开发DevEcoStudio准备-1

2. HarmonyOS应用开发DevEcoStudio准备-1 下载 DevEco Studio 进入HUAWEI DevEco Studio产品页产品页。 单击下载列表右侧的按钮&#xff0c;下载 DevEco Studio。 安装 DevEco Studio 下载完成后&#xff0c;双击下载的 deveco-studio-xxxx.exe&#xff0c;进入 DevEco St…

基于SSM的高校社团管理系统

末尾获取源码作者介绍&#xff1a;大家好&#xff0c;我是墨韵&#xff0c;本人4年开发经验&#xff0c;专注定制项目开发 更多项目&#xff1a;CSDN主页YAML墨韵 我欲乘风归去 又恐琼楼玉宇 高处不胜寒 -苏轼 目录 一、项目简介 二、开发技术与环境配置 2.1 SSM框架 2.2 …

vue中使用stomp.js

简介 STOMP即Simple (or Streaming) Text Orientated Messaging Protocol&#xff0c;简单(流)文本定向消息协议&#xff0c;它提供了一个可互操作的连接格式&#xff0c;允许STOMP客户端与任意STOMP消息代理&#xff08;Broker&#xff09;进行交互。STOMP协议由于设计简单&am…

洞悉智能新纪元:从基础AI到AIGC直至GAI的深度探索

引言 随着科技发展步入快车道&#xff0c;人工智能&#xff08;Artificial Intelligence, AI&#xff09;正以前所未有的速度渗透进我们的日常生活。本篇文章将通过详实的案例分析&#xff0c;帮助读者把握基础AI的核心功能&#xff0c;领略AI生成内容&#xff08;AIGC&#x…

使用STM32的FMC/FSMC接口实现多路数据传输和并发操作的设计与应用

在基于STM32的系统中&#xff0c;FMC&#xff08;Flexible Memory Controller&#xff09;/FSMC&#xff08;Flexible Static Memory Controller&#xff09;接口可以用于实现多路数据传输和并发操作。通过合理的设计和应用&#xff0c;我们可以提高系统的数据处理速度和效率。…

C++(20):通过concept及nlohmann将数据转换为字符串

nlohmann可以自动兼容将C++的很多原生类型转换为json,甚至自定义类型也不需要太复杂的操作就可以转换为json,可以利用这一点将数据转换为string: #include <nlohmann/json.hpp> #include <string> #include <vector> #include <tuple> #include <…

P1228 地毯填补问题

地毯填补问题 题目描述 相传在一个古老的阿拉伯国家里&#xff0c;有一座宫殿。宫殿里有个四四方方的格子迷宫&#xff0c;国王选择驸马的方法非常特殊&#xff0c;也非常简单&#xff1a;公主就站在其中一个方格子上&#xff0c;只要谁能用地毯将除公主站立的地方外的所有地…

关键字:extern ;什么时候类 对象 方法 定义在.h中;

2 关键字:extern 结论就是 严格是extern应该和头文件一起使用, 但是项目简单就可以直接使用? 在简单的项目或者临时的测试代码中&#xff0c;直接使用extern关键字而不通过头文件来声明外部函数或变量是可以的&#xff0c;这种情况下可能会更快捷一些。但是&#xff0c;即使在…

数据可视化 pycharts实现时间数据可视化

自用版 数据格式为&#xff1a; 运行效果为&#xff1a; from pyecharts import options as opts from pyecharts.charts import Polar, Page import csv filename "./hot-dog-places.csv" data_x [] data_y [] with open(filename) as f:reader csv.reade…

前端使用cache storage实现远程图片缓存

Cache Storage 的主要特点和用途 缓存网络资源&#xff1a;可以将经常访问的网络资源缓存到 Cache Storage 中&#xff0c;以提高网页加载速度&#xff0c;减少网络请求。离线访问&#xff1a;当用户处于离线状态时&#xff0c;可以使用 Cache Storage 中的缓存资源来加载网页…

【系统设计】12306架构设计难点(下)

欢迎关注公众号&#xff08;通过文章导读关注&#xff1a;【11来了】&#xff09;&#xff0c;及时收到 AI 前沿项目工具及新技术的推送&#xff01; 在我后台回复 「资料」 可领取编程高频电子书&#xff01; 在我后台回复「面试」可领取硬核面试笔记&#xff01; 文章导读地址…

实现两栏布局和三栏布局的多种详细方法

目录 一、背景两栏布局三栏布局 二、两栏布局flex弹性布局 三、三栏布局两边使用 float&#xff0c;中间使用 margin两边使用 absolute&#xff0c;中间使用 margin两边使用 float 和负 margin使用 display: table 实现使用flex实现grid网格布局 参考文献 一、背景 在日常布局…

永磁同步电机速度环闭环控制

文章目录 1、速度环分析2、电机参数3、PI计算4、模型仿真4.1 模型总览4.2 实际转速与参考转速对比4.3 转矩波形4.4 相电流采样波形 模型下载地址&#xff1a; 链接: 速度闭环模型&#xff08;速度电流双闭环&#xff09; 1、速度环分析 2、电机参数 Udc24 V Rs0.6 LdLq1.4e-3…

【2024美国大学生数学建模竞赛】2024美赛C题 问题分析、数学模型、实现代码、完整论文

【2023美国大学生数学建模竞赛】2024美赛C题 问题分析、数学模型、实现代码、完整论文 引言 题目将于2024年2月2日6:00发布。我们团队将会在8点前准时更新问题分析&#xff0c;逐步更新数学模型和实现代码&#xff0c;最后发布完整的论文。 更新进展&#xff1a; &#xff08;…

Java开发常用框架:效率框架、测试框架、日志框架、安全框架总结

目录 1、Java效率框架 1.Lombox 2.MapStruct 2、测试框架 1.JUnit 2.TestNG 3、日志框架 1.Log4j 2.SLF4J 4、安全框架 1.Spring Security 2.Apache Shiro 1、Java效率框架 常见Java效率框架&#xff1a;Lombox、MapStruct等。 1.Lombox Lombox和MapStruct都是常见…

docker导出conda环境的流程

要在 Docker 中导出 Conda 环境&#xff0c;需要创建一个 Docker 镜像&#xff0c;该镜像包含 Conda 环境。 步骤如下&#xff1a; 创建 Conda 环境并导出环境文件&#xff1a; 首先&#xff0c;在本地机器上创建一个 Conda 环境。 然后使用 conda env export > environme…