上一篇博客将了两个智能指针auto_ptr和unique_ptr。指路智能指针(一)
今天我们继续来了解剩下的两个智能指针,shared_ptr和weak_ptr.
shared_ptr
特点:强智能指针,带有引用计数的指针,实现智能指针共享数据
引用计数为0时,释放所指向的内存空间,所有权不唯一
缺点:智能指针相互引用,导致内存泄漏,
相互引用如图所示:
weak_ptr
特点:解决强智能指针shared_ptr相互引用的问题
不能单独使用 配合shared_ptr
不加引用计数
#include<memory>
class Ref_Man
{
public:
static Ref_Man* getInstance()
{
if (prm == NULL)
{
prm = new Ref_Man();
}
return prm;
}
int getRef(void* ptr)
{
if (ptr == NULL)
{
return -1;
}
int index = find(ptr);
if (index != -1)
{
return ref_count[index].count;
}
return -1;
}
void addRef(void* ptr)
{
if (ptr == NULL)
{
return;
}
int index = find(ptr);
if (index != -1)
{
ref_count[index].count++;
}
else
{
ref_count[cursize].addr = ptr;
ref_count[cursize++].count = 1;
}
}
void delRef(void* ptr)
{
if (ptr == NULL)
{
return;
}
int index = find(ptr);
if (index != -1)
{
if (getRef(ptr) != 0)
{
--ref_count[index].count;
}
}
}
private:
Ref_Man()
{
cursize = 0;
}
Ref_Man(const Ref_Man&);
int find(void* ptr)
{
int index = -1;
for (int i = 0; i < cursize; i++)
{
if (ref_count[i].addr == ptr)
{
index = i;
break;
}
}
return index;
}
typedef struct Ref
{
void* addr;
int count;
}Ref;
Ref ref_count[10];
int cursize;
static Ref_Man* prm;
};
Ref_Man* Ref_Man::prm = NULL;
template<typename T>
class Shared_Ptr
{
public:
Shared_Ptr(T* ptr = NULL)
:mptr(ptr)
{
prm->addRef(mptr);
}
Shared_Ptr(Shared_Ptr<T>& rhs)
{
mptr = rhs.mptr;
prm->addRef(mptr);
}
Shared_Ptr<T>& operator=(Shared_Ptr<T>&rhs)
{
if (this != &rhs)
{
prm->delRef(mptr);
if (prm->getRef(mptr))
{
delete mptr;
}
mptr = rhs.mptr;
prm->addRef(mptr);
}
return *this;
}
~Shared_Ptr()
{
prm->delRef(mptr);
if (prm->getRef(mptr) == 0)
{
delete mptr;
}
mptr = NULL;
}
T& operator*()
{
return *mptr;
}
T* operator->()
{
return mptr;
}
private:
T* mptr;
static Ref_Man* prm;
};
template<typename T>
Ref_Man* Shared_Ptr<T>::prm = Ref_Man::getInstance();
class B;
class A
{
public:
A()
{
std::cout << "A::A()" << std::endl;
}
~A()
{
std::cout << "A::~A()" << std::endl;
}
public:
std::weak_ptr<B> spa;
};
class B
{
public:
B()
{
std::cout << "B::B()" << std::endl;
}
~B()
{
std::cout << "B::~B()" << std::endl;
}
public:
std::weak_ptr<A> spb;
};
int main()
{
std::shared_ptr<A> pa(new A());
std::shared_ptr<B> pb(new B());
pa->spa = pb;
pb->spb = pa;
return 0;
}
int main()
{
int* p = new int;
Shared_Ptr<int> sp1(p);
Shared_Ptr<double> spd = new double;
Shared_Ptr<int> sp2(p);
Shared_Ptr<int> sp3(p);
return 0;
}