本文主要是介绍两种智能指针-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智能指针和引用计数智能指针的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!