两种智能指针-RAII智能指针和引用计数智能指针
2015-11-17 23:46
507 查看
两种智能指针-RAII智能指针和引用计数智能指针
两种智能指针-RAII智能指针和引用计数智能指针RAII简介
RAII智能指针代码参考
引用计数版本参考代码
转载请注明出处
RAII简介
RAII的全称是:Resource Acquisition Is Initialization 也就是“资源获取就是初始化”。就像内存分配是在变量初始化的时候分配的;比如,当程序结束时,系统会自动释放程序所使用的资源;函数传值时,当函数调用结束,该值也将消亡。RAII智能指针代码参考
#include <iostream> #define SAFE_DELETE(ptr) if(nullptr!=ptr){delete ptr;ptr=nullptr;}//安全delete template<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; }
注:代码尚有缺点。
转载请注明出处
相关文章推荐
- AVL树笔记(二):maintain,delete
- (转)RabbitMQ消息队列(一): Detailed Introduction 详细介绍
- Once you eliminate all the other factors,the only thing remaining must be the truth.
- fail-fast机制
- Kafka设计解析(二)- Kafka High Availability (上)
- 关于int main(int argc,char*argv[])的玩意
- hdu 2389 Rain on your Parade 二分图匹配+HK算法
- Adb failed to restart! Make sure the plugin is properly configured.
- 关于container_of和list_for_each_entry 及其相关函数的分析
- OC中retain和assign的setter方法的写法和区别
- 【MFC】关于AfxGetMainWnd导致VS2010运行结果崩溃的解法
- Daily Scrum - 11/17
- http://blog.csdn.net/lifeitengup/article/details/8666182
- HDU---1151-Air Raid(二分图)(HDU-1150)(POJ-3041)
- POJ 1422 Air Raid 最小覆盖点
- pthread_cond_wait
- UVA 题目10617 - Again Palindrome(区间DP)
- poj 1422 Air Raid(最小路径覆盖)
- LeetCode:Factorial Trailing Zeroes
- LeetCode:Contains Duplicate II