为什么要使用智能指针
使用裸指针存在资源泄露问题
智能指针在栈上保证了资源的自动释放
不带引用计数的智能指针
auto_ptr:原来的auto_ptr置空,只有最新的auto_ptr指针才能访问资源
scope_ptr:把拷贝构造和=运算符重载设为私有导致编译失败
unique_ptr:只有用move才能将资源转到另一个unique_ptr
带引用计数的智能指针
shared_ptr:是线程安全的,强智能指针(可以改变资源的引用计数)
weak_ptr:弱智能指针(不能改变资源的引用计数)
基于两者的强弱之分所以创建对象的时候用强智能指针,其他地方一律用弱智能指针,避免智能指针的循环引用。
自己实现带引用计数的强智能指针:
#include "stdafx.h"
#include <iostream>
#include <memory>
#include <list>
using namespace std;
class ResList
{
public:
//给ptr资源增加引用计数
void addRef(void *ptr)
{
list<Node>::iterator it = nodeList.begin();
for (; it != nodeList.end(); ++it)
{
if (ptr == it->_resptr)
{
it->_count++;
}
}
nodeList.push_back(Node(ptr));
}
//给ptr资源删除引用计数
int delRef(void *ptr)
{
list<Node>::iterator it = nodeList.begin();
for (; it != nodeList.end(); ++it)
{
if (ptr == it->_resptr)
{
it->_count--;
if (it->_count == 0)
{
nodeList.erase(it);
}
return it->_count;
}
}
return -1;
}
private:
struct Node
{
Node(void *ptr = NULL) :_resptr(ptr), _count(1)
{
}
void *_resptr;
int _count;
};
list<Node> nodeList;
};
template<typename T>
class CSmartPtr
{
public:
CSmartPtr(T *ptr = NULL) :mptr(ptr)
{
if (mptr != NULL)
resList.addRef(ptr);
}
CSmartPtr(const CSmartPtr<T> &src) :mptr(src.mptr)
{
if (mptr != NULL)
{
resList.addRef(mptr);
}
}
CSmartPtr<T>& operator=(const CSmartPtr<T> &src)
{
if (this == &src)
{
return *this;
}
if (0 == resList.delRef(mptr))
{
delete mptr;
}
mptr = src.mptr;
resList.addRef(mptr);
return *this;
}
~CSmartPtr()
{
if (0 == resList.delRef(mptr))
{
delete mptr;
}
}
T& operator*() { return *mptr; }
T* operator->() { return mptrl; }
private:
T * mptr;
static ResList resList;
};
template<typename T>
ResList CSmartPtr<T>::resList;