shared_ptr共享智能指针(实现以及缺陷)

shared_ptr共享指针是C++11提供的更加可靠的智能指针,它支持拷贝赋值

shared_ptr实现的原理:通过引用计数的方式来实现多个shared_ptr对象共享一份资源。RAII的思想、重载* ->、引用计数解决浅拷贝问题。

采用mutex来保证线程安全,mutex只能保证对引用计数的安全性,对于shared_ptr管理的资源由用户去保证。

  1. shared_ptr 在其内部, 给每个资源都维护了着一份计数,用来记录该份资源被几个对象共享
  2. 对象被销毁时 ( 也就是析构函数调用 ) ,就说明自己不使用该资源了,对象的引用计数减一。
  3. 如果引用计数是 0 ,就说明自己是最后一个使用该资源的对象, 必须释放该资源
  4. 如果不是 0 ,就说明除了自己还有其他对象在使用该份资源, 不能释放该资源 ,否则其他对象就成野指
    针了。
namespace bite
{
	template
	class DeleteDef
	{
	public:
		void operator()(T*& p)
		{
			if(p)
			{
				delete p;
				p = nullptr;
			}
		}
	};

	template
	class Free
	{
	public:
		void operator()(T*& p)
		{
			if(p)
			{
				free(p);
				p = nullptr;
			}
		}
	};

	template
	class FClose
	{
	public:
		void operator()(FILE*& p)
		{
			if(p)
			{
				fclose(p);
				p = nullptr;
			}
		}
	};
	template>
	class shared_ptr
	{
	public:
		shared_ptr(T* ptr = nullptr)
			:_ptr(ptr)
			,_pcount(nullptr)
			,_pmutex(nullptr)
		{
			
			if(ptr)
			{
				_pcount = new int(1);
				_pmutex = new mutex;
			}
		}

		~shared_ptr()
		{
			_func();
		}

		T& operator*()
		{
			return *_ptr;
		}

		T* operator->()
		{
			return _ptr;
		}
		T* get()
		{
			return _ptr;
		}
		
		// 解决浅拷贝:引用计数
		shared_ptr(const shared_ptr& sp)
			:_ptr(sp._ptr)
			,_pcount(sp._pcount)
		{
			if(_ptr)
			{
				AddRef();
			}
		}
		shared_ptr& operator=(const shared_ptr& sp)
		{
			if(this!= &sp)
			{
				// *thsi = sp;
				// *this使用sp的共享资源
				// *this可能本来就拥有资源,如果再去和sp共享一份资源,那么它的之前的资源就不用了
				// *this管理资源的计数可能是 1 或者 大于 1
				// *this应该对其资源的计数-1
				_func();
				// 让*this和sp共享资源
				_ptr = sp._ptr;
				_pcount = sp._pcount;
				if(_ptr)
				{
					AddRef();
				}
			}
			return *this;
		}
		int use_count()const
		{
			if(_pcount == nullptr)
				throw bad_exception();

			return *_pcount;
		}
	private:
		void _func()
		{
			if(_ptr && 0 == SubRef())
			{
				DX() (_ptr);
				_ptr = nullptr;

				delete _pcount;
				_pcount = nullptr;
			}
		}

		int SubRef()  // -- 是线程安全
		{
			_pmutex->lock();
			--(*_pcount);
			_pmutex->unlock();
			
			return *_pcount;
		}

		void AddRef() // ++ 是线程安全
		{
			_pmutex->lock();
			++(*_pcount);
			_pmutex->unlock();
		}
	private:
		T* _ptr;
		T* _pcount;
		mutex* _pmutex;
	};
}

shared_ptr的缺陷:shared_ptr的缺陷是由于引用计数引起的循环引用的问题

 

 

 

 

 

 

 

 

 

 

你可能感兴趣的:(shared_ptr共享智能指针(实现以及缺陷))