shared_ptr
shared_ptr特点:
- 不能隐式构造
 - 不能将同一个裸指针赋值给多个智能指针
 - 允许并且可以进行拷贝构造和等号运算符重载
 - 每个shared_ptr对象在内部指向两个内存位置:指向对象的指针;用于控制引用计数的指针
 
共享所有权如何使用引用计数:
- 当新的shared_ptr对象与指针相关联时,则在其构造函数汇总,将与此指针相关量的引用计数加1.
 - 当任何shared_ptr对象超出作用域时,则在其析构函数中,它将关联指针的引用计数减1
 - 如果引用计数减为0,则表示没有shared_ptr对象与原始指针关联,在这种情况下,它就会使用delete函数来释放该内存。
 - shared_ptr对象的所有权可以转移
创建shared_ptr对象: 
    int* p = new int(99);
	Mshared_ptr<int>s_p1(p);
    Mshared_ptr<int>s_p1=make_shared<int>();
 
上述两种方式都可创建对象,但是使用make_shared会开辟了两块内存:一块存储int值,一块存储引用计数。而new只能开辟存放int值的空间
 引用计数:
s_p1.use_count();//初始值为1
 
拷贝构造函数:
    Mshared_ptr(const Mshared_ptr& src)
	{
	    //如果此shared_ptr对象红黑树中没有找到,则插入进去,并没有重新开辟空间
		if (_count.end() == _count.find(_ptr))
		{
			_count.insert(make_pair(src._ptr, 1));
		}
		_ptr = src._ptr;
		_count[_ptr]++;//引用计数加一
	}
 
等号运算符重载:
Mshared_ptr& operator=(const Mshared_ptr& src)
	{
		if (this == &src)//防止自赋值
		{
			return *this;
		}
		if (_count.end() == _count.find(src._ptr))
		{
			_count.insert(make_pair(src._ptr, 1));
		}
		_ptr = src._ptr;
		_count[_ptr]++;
		return *this;
	}
 
减少与原始指针相关联的对象:
	void reset()
	{
		if (unique())
		{
			delete _ptr;
		}
		else
		{
			_count[_ptr]--;
		}
		_ptr = NULL;
	}
 
判断是否还有与原始指针关联的对象:
bool unique()
	{
		if (_count.end() == _count.find(_ptr) || _count[_ptr] == 1)
		{
			return true;
		}
		return false;
	}
 
返回引用计数:
   int use_count()
	{
		if (_count.end() == _count.find(_ptr))
		{
			return 1;
		}
		return _count[_ptr];
	}
 
获取内部指针:
	T* get()
	{
		return _ptr;
	}
 
完整代码示例:
emplate<typename T>
class Mshared_ptr
{
public:
	explicit Mshared_ptr(T* ptr = NULL)
	{
		_ptr = ptr;
	}
	Mshared_ptr(const Mshared_ptr& src)
	{
		if (_count.end() == _count.find(_ptr))
		{
			_count.insert(make_pair(src._ptr, 1));
		}
		_ptr = src._ptr;
		_count[_ptr]++;
	}
	Mshared_ptr& operator=(const Mshared_ptr& src)
	{
		if (this == &src)
		{
			return *this;
		}
		if (unique())
		{
			delete _ptr;
		}
		else
		{
			_count[_ptr]--;
		}
		if (_count.end() == _count.find(src._ptr))
		{
			_count.insert(make_pair(src._ptr, 1));
		}
		_ptr = src._ptr;
		_count[_ptr]++;
		return *this;
	}
	~Mshared_ptr()
	{
		if (unique())
		{
			delete _ptr;
		}
		else
		{
			_count[_ptr]--;
		}
	}
	T* get()
	{
		return _ptr;
	}
	void reset()
	{
		if (unique())
		{
			delete _ptr;
		}
		else
		{
			_count[_ptr]--;
		}
		_ptr = NULL;
	}
	bool unique()
	{
		if (_count.end() == _count.find(_ptr) || _count[_ptr] == 1)
		{
			return true;
		}
		return false;
	}
	int use_count()
	{
		if (_count.end() == _count.find(_ptr))
		{
			return 1;
		}
		return _count[_ptr];
	}
	T&operator*()
	{
		return *_ptr;
	}
	T*operator->()
	{
		return _ptr;
	}
	operator bool()
	{
		return _ptr != NULL;
	}
	//template<typename Ty>
	//friend class Mweak_ptr<Ty>
private:
	T* _ptr;
	static map<T*,int> _count;
};
 
template<typename T>
map<T*,int> Mshared_ptr<T>::_count = map<T*,int>();
int main()
{
	int* p = new int(99);
	Mshared_ptr<int>s_p1(p);
	//Mshared_ptr<int>s_p2(p);
	Mshared_ptr<int>s_p3 = s_p1;
	Mshared_ptr<int>s_p4;
	s_p4 = s_p1;
	cout << *s_p1 << endl;
	cout << *s_p3 << endl;
	cout << *s_p4 << endl;
	Mshared_ptr<int>s_p5=move(s_p4);//转移s_p4的所有权给s_p5
	//s_p4.reset();
	//s_p4.get();
	//s_p4[];
	//s_p4.unique();//判断当前的引用计数是否为1,独有的
	cout << s_p3.use_count() << endl;
	cout << s_p4.use_count() << endl;
}









