您的位置:首页 > 大数据 > 人工智能

两种智能指针-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;
}


注:代码尚有缺点。

转载请注明出处

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: