两种智能指针-RAII智能指针和引用计数智能指针

2023-10-30 10:08

本文主要是介绍两种智能指针-RAII智能指针和引用计数智能指针,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

两种智能指针-RAII智能指针和引用计数智能指针

  • 两种智能指针-RAII智能指针和引用计数智能指针
    • RAII简介
    • RAII智能指针代码参考
    • 引用计数版本参考代码
  • 转载请注明出处

RAII简介

RAII的全称是:Resource Acquisition Is Initialization 也就是“资源获取就是初始化”。就像内存分配是在变量初始化的时候分配的;比如,当程序结束时,系统会自动释放程序所使用的资源;函数传值时,当函数调用结束,该值也将消亡。

RAII智能指针代码参考

#include <iostream>#define SAFE_DELETE(ptr) if(nullptr!=ptr){delete ptr;ptr=nullptr;}//安全deletetemplate<typename T>class SmartPtr{
public:typedef T element_type;explicit SmartPtr(T * ptr=nullptr):m_ptr(ptr){}SmartPtr(SmartPtr<T> & ptr):m_ptr(ptr.release()){}inline T * release(){T * tmp=m_ptr;SAFE_DELETE(m_ptr);return m_ptr;}SmartPtr<T>& operator=(SmartPtr<T>& ptr){if(&ptr != this){SAFE_DELETE(m_ptr);m_ptr=ptr.release();}return *this;}SmartPtr<T>& operator= (T * ptr){if(ptr!=ptr.get()){SAFE_DELETE(m_ptr);m_ptr=ptr.release();}return *this;}~SmartPtr(){SAFE_DELETE(m_ptr);}inline T * operator->(){return m_ptr;}inline T & operator*(){return *m_ptr;}inline void reset(T * ptr=nullptr){SAFE_DELETE(m_ptr);m_ptr=ptr;}inline T * get()const{return m_ptr;}private:T * m_ptr;
};int main(){SmartPtr<int>ptr(new int(234));std::cout<<*ptr<<std::endl;std::cout<<*ptr.get()<<std::endl;return 0;
}

第二种写法:

#include <iostream>template<typename T>
inline void SafeDelete(T*& ptr) {if (ptr != nullptr) {delete ptr;ptr = nullptr;}
}template<typename T>
class SmartPtr {
public:SmartPtr() :m_ptr(nullptr) {}SmartPtr(T * ptr):m_ptr(ptr){}SmartPtr(const SmartPtr<T> & other) = delete;template<typename Tx>SmartPtr(const SmartPtr<Tx> & other) = delete;SmartPtr(SmartPtr<T>&&other){T *ptr = other.m_ptr;other.m_ptr = m_ptr;m_ptr = ptr;}~SmartPtr() { SafeDelete(m_ptr); }SmartPtr & operator=(const SmartPtr<T>& other) = delete;template<typename Tx>SmartPtr & operator=(const SmartPtr<Tx>&other) = delete;SmartPtr & operator=(const SmartPtr<T>&&other) {if (this != &other) {T *ptr = other.m_ptr;other.m_ptr = m_ptr;m_ptr = ptr;}}inline T & operator*() {return *m_ptr;}inline T * operator->() {return m_ptr;}inline const T & operator*()const {return *m_ptr;}inline const T * operator->()const {return m_ptr;}inline T * release(){T * bk = m_ptr;m_ptr = nullptr;return bk;}inline void reset(T * ptr = nullptr) {SafeDelete(m_ptr);m_ptr = ptr;}inline T * get() { return m_ptr; }inline const T * get()const { return m_ptr; }
private:T * m_ptr;
};struct My {int data = 100;
};int main() {SmartPtr<int> ptr(new int(2342));std::cout << *ptr << std::endl;SmartPtr<My> ptrx(new My);std::cout << ptrx->data << std::endl;std::cin.get();return 0;
}

引用计数版本参考代码

引用计数使用到了代理模式的相关知识:参考
http://baike.baidu.com/view/2645890.htm

#include <iostream>
#include <windows.h>#define SAFE_DELETE(ptr) if(ptr!=nullptr){delete ptr;ptr=nullptr;}class RefCount{
public:RefCount():m_count(0){}~RefCount(){}unsigned long AddRef(){return InterlockedIncrement(reinterpret_cast<long *>(&m_count));}unsigned long Release(){return InterlockedDecrement(reinterpret_cast<long *>(&m_count));}inline void Reset(){m_count=0;}
private:unsigned long m_count;
};template<typename T>class SmartPtr{
public:typedef T element_type;explicit SmartPtr():m_ptr(nullptr),m_counter(new RefCount){m_counter->AddRef();}SmartPtr(T * ptr):m_ptr(ptr),m_counter(new RefCount){m_counter->AddRef();}SmartPtr(const SmartPtr<T>& ptr)=delete;SmartPtr(SmartPtr<T>&& ptr):m_ptr(ptr.m_ptr),m_counter(ptr.m_counter){ptr.m_ptr=nullptr;ptr.m_counter=nullptr;}SmartPtr<T>& operator=(const SmartPtr<T>& ptr)=delete;SmartPtr<T>& operator=(SmartPtr<T>&& ptr){if(m_counter && m_counter->Release()==0){SAFE_DELETE(m_ptr);SAFE_DELETE(m_counter);}m_ptr=ptr.m_ptr;ptr.m_ptr=nullptr;m_counter=ptr.m_counter;ptr.m_counter=nullptr;return *this;}SmartPtr<T>& operator=(T * ptr){if(ptr != m_ptr){if(m_counter && m_counter->Release()==0){SAFE_DELETE(m_ptr);m_counter->Reset();}m_ptr=ptr;m_counter->AddRef();}}inline T * get()const{return m_ptr;}inline T & operator*(){return *m_ptr;}inline T * operator->(){return m_ptr;}inline void swap(SmartPtr<T> & ptr){T * tmp=ptr.m_ptr;RefCount * rtmp=ptr.m_counter;ptr.m_ptr=m_ptr;ptr.m_counter=m_counter;m_ptr=tmp;m_counter=rtmp;}inline T * release(){T * tmp=m_ptr;m_ptr=nullptr;return m_ptr;}private:RefCount * m_counter;T * m_ptr;
};int main(){SmartPtr<int>ptr(new int(2432));std::cout<<*ptr<<std::endl;std::cout<<*ptr.get()<<std::endl;return 0;
}

关于InterlockedIncrement和InterlockedDecrement参考:
http://baike.baidu.com/view/6235756.htm

版本2:

#include <iostream>
#include <Windows.h>template<typename T>
inline void SafeDelete(T*& ptr) {if (ptr != nullptr) {delete ptr;ptr = nullptr;}
}class RefCounter {
public:RefCounter():m_cnt(0){}~RefCounter() {}std::size_t RefAdd() { return InterlockedIncrement(&m_cnt); }std::size_t Release() { return InterlockedDecrement(&m_cnt); }std::size_t getcnt() { return m_cnt; }void reset() { m_cnt = 0; }
private:size_t m_cnt;
};template<typename T>
class SmartPtr {
public:SmartPtr() :m_ptr(nullptr) ,m_counter(new RefCounter){m_counter->RefAdd();}SmartPtr(T * ptr) :m_ptr(ptr), m_counter(new RefCounter) {m_counter->RefAdd();}SmartPtr(const SmartPtr<T>& other) = delete;template<typename Tx>SmartPtr(const SmartPtr<Tx>&other) = delete;SmartPtr(SmartPtr<T>&&other) :m_ptr(other.m_ptr),m_counter(other.m_counter){other.m_ptr = nullptr;other.m_counter = nullptr;}~SmartPtr() {if (m_counter != nullptr && m_counter->Release() == 0) {SafeDelete(m_ptr);SafeDelete(m_counter);}}SmartPtr & operator=(const SmartPtr<T>& other) = delete;template<typename Tx>SmartPtr & operator=(const SmartPtr<Tx>& other) = delete;SmartPtr & operator=(SmartPtr<T>&&other) {if (&other != this) {if (m_counter != nullptr && m_counter->Release() == 0) {SafeDelete(m_ptr);SafeDelete(m_counter);}m_ptr = other.m_ptr;m_counter = new RefCounter;m_counter->RefAdd();}}T * relaese() {if (m_counter != nullptr && m_counter->Release() == 0) {SafeDelete(m_ptr);SafeDelete(m_counter);}m_ptr = nullptr;m_counter = nullptr;}void reset(T * ptr = nullptr) {if (m_counter != nullptr && m_counter->Release() == 0) {SafeDelete(m_ptr);SafeDelete(m_counter);}m_ptr = ptr;m_counter = new RefCounter;m_counter->RefAdd();}T & operator*() { return *m_ptr; }const T & operator*()const { return *m_ptr; }T*operator->() { return m_ptr; }const T*operator->()const { return m_ptr; }
private:T * m_ptr;RefCounter * m_counter;
};struct My {int data = 1000;
};int main() {SmartPtr<My> ptr(new My);std::cout << ptr->data << std::endl;SmartPtr<double> ptrx(new double(24.2));std::cout << *ptrx << std::endl;std::cin.get();return 0;
}

注:代码尚有缺点。

转载请注明出处

这篇关于两种智能指针-RAII智能指针和引用计数智能指针的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/307164

相关文章

嵌入式QT开发:构建高效智能的嵌入式系统

摘要: 本文深入探讨了嵌入式 QT 相关的各个方面。从 QT 框架的基础架构和核心概念出发,详细阐述了其在嵌入式环境中的优势与特点。文中分析了嵌入式 QT 的开发环境搭建过程,包括交叉编译工具链的配置等关键步骤。进一步探讨了嵌入式 QT 的界面设计与开发,涵盖了从基本控件的使用到复杂界面布局的构建。同时也深入研究了信号与槽机制在嵌入式系统中的应用,以及嵌入式 QT 与硬件设备的交互,包括输入输出设

让树莓派智能语音助手实现定时提醒功能

最初的时候是想直接在rasa 的chatbot上实现,因为rasa本身是带有remindschedule模块的。不过经过一番折腾后,忽然发现,chatbot上实现的定时,语音助手不一定会有响应。因为,我目前语音助手的代码设置了长时间无应答会结束对话,这样一来,chatbot定时提醒的触发就不会被语音助手获悉。那怎么让语音助手也具有定时提醒功能呢? 我最后选择的方法是用threading.Time

智能交通(二)——Spinger特刊推荐

特刊征稿 01  期刊名称: Autonomous Intelligent Systems  特刊名称: Understanding the Policy Shift  with the Digital Twins in Smart  Transportation and Mobility 截止时间: 开放提交:2024年1月20日 提交截止日

基于 YOLOv5 的积水检测系统:打造高效智能的智慧城市应用

在城市发展中,积水问题日益严重,特别是在大雨过后,积水往往会影响交通甚至威胁人们的安全。通过现代计算机视觉技术,我们能够智能化地检测和识别积水区域,减少潜在危险。本文将介绍如何使用 YOLOv5 和 PyQt5 搭建一个积水检测系统,结合深度学习和直观的图形界面,为用户提供高效的解决方案。 源码地址: PyQt5+YoloV5 实现积水检测系统 预览: 项目背景

【C++学习笔记 20】C++中的智能指针

智能指针的功能 在上一篇笔记提到了在栈和堆上创建变量的区别,使用new关键字创建变量时,需要搭配delete关键字销毁变量。而智能指针的作用就是调用new分配内存时,不必自己去调用delete,甚至不用调用new。 智能指针实际上就是对原始指针的包装。 unique_ptr 最简单的智能指针,是一种作用域指针,意思是当指针超出该作用域时,会自动调用delete。它名为unique的原因是这个

C语言指针入门 《C语言非常道》

C语言指针入门 《C语言非常道》 作为一个程序员,我接触 C 语言有十年了。有的朋友让我推荐 C 语言的参考书,我不敢乱推荐,尤其是国内作者写的书,往往七拼八凑,漏洞百出。 但是,李忠老师的《C语言非常道》值得一读。对了,李老师有个官网,网址是: 李忠老师官网 最棒的是,有配套的教学视频,可以试看。 试看点这里 接下来言归正传,讲解指针。以下内容很多都参考了李忠老师的《C语言非

单片机毕业设计基于单片机的智能门禁系统的设计与实现

文章目录 前言资料获取设计介绍功能介绍程序代码部分参考 设计清单具体实现截图参考文献设计获取 前言 💗博主介绍:✌全网粉丝10W+,CSDN特邀作者、博客专家、CSDN新星计划导师,一名热衷于单片机技术探索与分享的博主、专注于 精通51/STM32/MSP430/AVR等单片机设计 主要对象是咱们电子相关专业的大学生,希望您们都共创辉煌!✌💗 👇🏻 精彩专栏 推荐订

JavaSE(十三)——函数式编程(Lambda表达式、方法引用、Stream流)

函数式编程 函数式编程 是 Java 8 引入的一个重要特性,它允许开发者以函数作为一等公民(first-class citizens)的方式编程,即函数可以作为参数传递给其他函数,也可以作为返回值。 这极大地提高了代码的可读性、可维护性和复用性。函数式编程的核心概念包括高阶函数、Lambda 表达式、函数式接口、流(Streams)和 Optional 类等。 函数式编程的核心是Lambda

C和指针:字符串

字符串、字符和字节 字符串基础 字符串就是一串零个或多个字符,并且以一个位模式为全0的NUL字节结尾。 字符串长度就是字符串中字符数。 size_t strlen( char const *string ); string为指针常量(const修饰string),指向的string是常量不能修改。size_t是无符号数,定义在stddef.h。 #include <stddef.h>

【C++】作用域指针、智能指针、共享指针、弱指针

十、智能指针、共享指针 从上篇文章 【C++】如何用C++创建对象,理解作用域、堆栈、内存分配-CSDN博客 中我们知道,你的对象是创建在栈上还是在堆上,最大的区别就是对象的作用域不一样。所以在C++中,一旦程序进入另外一个作用域,那其他作用域的对象就自动销毁了。这种机制有好有坏。我们可以利用这个机制,比如可以自动化我们的代码,像智能指针、作用域锁(scoped_lock)等都是利用了这种机制。