关于为什么要用智能指针,不需要做太多的赘述了。主要还是为了帮助管理申请的堆空间,程序员很有可能会忘了自己的申请空间。
提供的智能指针包括auto_ptr、unique_ptr、weak_ptr、shared_ptr几中。
其中auto_ptr最弱,建议不要使用。unique_ptr顾名思义不能共享指向同一内存空间,如果非要这么干,会在编译时报错。但是也不是绝对的,如果unique_ptr是一个要被回收的临时对象,那么它可以作为右值被拷贝给另一变量。
shared_ptr是可以共享的智能指针,它是使用的引用计数的方式,确定有多少个智能指针在共享同一内存空间,当引用计数变为0时,内存空间被回收。
weak_ptr是弱指针,存在的意义主要是为了辅助shared_ptr解决循环引用的问题。所谓的循环引用,例如,有两个堆区对象A和B,他们分别由智能指针pA和pB管理,然后在A对象内有一个指向B对象的智能指针,在B中有一个指向A对象的智能指针。当pA和pB生命周期结束,它们类内共享指针的引用计数仍然都为1,这就造成了一个互相保持类似于死锁的情况,会造成谁的空间都无法释放,进而有了内存泄漏。
在这里,我主要是模仿简单实现了类似于shared_ptr的智能指针,希望大家指正。
#ifndef __INCLUDE_SHARED_PTR_H__
#define __INCLUDE_SHARED_PTR_H__
#include <windows.h>
#include <iostream>
namespace HandsomeWang
{
template<typename T>
class shared_ptr;
/*计数器管理类,负责管理计数器的引用计数,和智能指针所指向的空间*/
template<typename T>
class shared_counter
{
private:
template<typename T>
friend class shared_ptr;
unsigned int m_uCount;
T* m_pMem;
shared_counter(T* pMem) :m_uCount(1), m_pMem(pMem)
{
}
~shared_counter()
{
std::cout <<"delet success "<<endl;
delete m_pMem;
}
};
//共享指针类
template<typename T>
class shared_ptr
{
public:
explicit shared_ptr(T* pMem) :m_pShared_counter(new shared_counter<T>(pMem))
{
}
~shared_ptr()
{
if (InterlockedDecrement(&(m_pShared_counter->m_uCount)) == 0)
{
delete m_pShared_counter;
}
}
shared_ptr(const shared_ptr<T> & ptr) :m_pShared_counter(ptr.m_pShared_counter)
{
InterlockedIncrement(&(m_pShared_counter->m_uCount));
}
shared_ptr& operator=(const shared_ptr<T> & ptr)
{
//防止自我赋值,现将ptr的引用计数加1
InterlockedIncrement(&(ptr.m_pShared_counter->m_uCount));
//再将this的引用计数减1,如果为0,就释放空间
if (InterlockedDecrement(&(m_pShared_counter->m_uCount)) == 0)
{
delete m_pShared_counter;
}
m_pShared_counter = ptr.m_pShared_counter;
return *this;
}
T& operator*()
{
return *m_pShared_counter->m_pMem;
}
T* operator ->()
{
return m_pShared_counter->m_pMem;
}
private:
shared_counter<T> *m_pShared_counter;
};
}
#endif//!__INCLUDE_SHARED_PTR_H__