shared_ptr是使用引用计数的智能指针,引用计数的智能指针可以跟踪引用同一个真实指针对象的智能指针实例的数目。这意味着,可以有多个shared_ptr实例指向同一块动态分配的内存,当最后一个引用对象离开其作用域时,才会释放这块内存。
本文采用两种方式存储引用计数,一种采用int* 指针存储引用计数,另一种使用map存储。
1、使用int* 指针指向引用计数
template<typename T>
struct Shared_Ptr_Point {
Shared_Ptr_Point(T *ptr = NULL) :m_ptr(ptr), count(new int(1))
{
cout << "Construct!" << endl;
}
~Shared_Ptr_Point()
{
if (0 == --*count)
{
cout << "Destruct!" << endl;
delete count;
count = NULL;
if (m_ptr)
{
delete m_ptr;
m_ptr = NULL;
}
}
}
Shared_Ptr_Point(const Shared_Ptr_Point<T>& other): count(&(++*other.count)), m_ptr(other.m_ptr) {}
Shared_Ptr_Point<T>& operator=(const Shared_Ptr_Point<T>& other);
T* operator->() { return m_ptr; }
T& operator*() { return *m_ptr; }
int getCount() const
{
return *count;
}
private:
T * m_ptr;
int *count; //使用int*而不使用int,保证当前对象的引用计数变化时,与之有关的对象的引用计数同时变化
};
template<typename T>
Shared_Ptr_Point<T>& Shared_Ptr_Point<T>::operator=(const Shared_Ptr_Point<T>& other)
{
++*other.count;
if (0 == --*this->count)
{
delete count;
if (this->m_ptr)
{
delete m_ptr;
}
}
m_ptr = other.m_ptr;
count = other.count;
return *this;
}
2、使用map存储引用计数
template<typename T>
struct Shared_Ptr_Map {
Shared_Ptr_Map(T *ptr= NULL);
~Shared_Ptr_Map();
Shared_Ptr_Map(const Shared_Ptr_Map<T> &other);
Shared_Ptr_Map<T>& operator=(const Shared_Ptr_Map<T> ðer);
int getCount() const;
T* operator->() { return m_ptr; }
T& operator*() { return *m_ptr; }
private:
T * m_ptr;
static map<T*, int> mapRepo; //map是static类型,是该类共有的
};
template<typename T>
map<T*, int> Shared_Ptr_Map<T>::mapRepo;
template<typename T>
Shared_Ptr_Map<T>::Shared_Ptr_Map(T *ptr) :m_ptr(ptr)
{
cout << "Construct!" << endl;
if (NULL != m_ptr)
{
mapRepo.insert(make_pair(m_ptr, 1));
}
}
template<typename T>
Shared_Ptr_Map<T>::~Shared_Ptr_Map()
{
if (--mapRepo[m_ptr] <= 0 && m_ptr)
{
cout << "Destruct!" << endl;
delete m_ptr;
m_ptr = NULL;
mapRepo.erase(m_ptr);
}
}
template<typename T>
Shared_Ptr_Map<T>::Shared_Ptr_Map(const Shared_Ptr_Map<T>& other) : m_ptr(other.m_ptr)
{
mapRepo[m_ptr]++;
}
template<typename T>
Shared_Ptr_Map<T>& Shared_Ptr_Map<T>::operator=(const Shared_Ptr_Map<T>& other)
{
++mapRepo[other.m_ptr];
if (m_ptr && 0 == --mapRepo[m_ptr])
{
delete m_ptr;
mapRepo.erase(m_ptr);
}
m_ptr = other.m_ptr;
return *this;
}
template<typename T>
int Shared_Ptr_Map<T>::getCount() const
{
return mapRepo[m_ptr];
}
后续补充在多线程情况下shared_ptr的使用…