shared_ptr的作用

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了shared_ptr的作用相关的知识,希望对你有一定的参考价值。

参考技术A

这便是所谓的引用计数(reference counting)。一旦最后一个这样的指针被销毁,也就是一旦某个对象的引用计数变为0,这个对象会被自动删除。这在非环形数据结构中防止资源泄露很有帮助。
auto_ptr由于它的破坏性复制语义,无法满足标准容器对元素的要求,因而不能放在标准容器中;如果我们希望当容器析构时能自动把它容纳的指针元素所指的对象删除时,通常采用一些间接的方式来实现,显得比较繁琐。boost库中提供了一种新型的智能指针shared_ptr,它解决了在多个指针间共享对象所有权的问题,同时也满足容器对元素的要求,因而可以安全地放入容器中。

boost::shared_ptr与定制删除器

技术分享shared_ptr

     shared_ptr是一种智能指针,他的作用如同指针,但会记录有多少shared_ptr指向同一个对象。使用时必须引用头文件<boost/shared_ptr.hpp>

template<class T>
class ShartedPtr
{
public:
	//构造函数
	ShartedPtr(T* ptr)
	:_ptr(ptr)
	, _pCount(new int(1))
	{
	}
	//拷贝构造
	ShartedPtr(const ShartedPtr<T>&sp)
		:_ptr(sp._ptr)
		, _pCount(sp._pCount)
	{
		++(*_pCount);
	}
	//赋值
	ShartedPtr&operator = (ShartedPtr<T>sp)
	{
		swap(_ptr, sp._ptr);
		swap(_pCount, sp._pCount);

		return *this;
	}
	//重载*
	T &operator*()
	{
		return *_ptr;
	}
	//重载->
	T *operator->()
	{
		return _ptr;
	}
	//析构函数
	~ShartedPtr()
	{
		Relase();
	}
protected:
	void Relase()
	{
		if (--(*_pCount) == 0)
		{
			delete _ptr;
			delete _pCount;
		}
	}
private:
	T* _ptr;
	int *_pCount;
};
struct A
{
	int _A;
};
int main()
{
	ShartedPtr<int> sp1(new int(1));
	ShartedPtr<int> sp2(sp1);
	sp1 = sp2;
	ShartedPtr<int> sp3(sp2);
	*sp3 = 10;
	ShartedPtr<A>sp4(new A);
	sp4->_A = 30;
	return 0;
}

 技术分享但是shared_ptr也存在一系列问题

  1. 引用计数存在线程安全问题

  2. 会出现循环引用问题

  3. 定制删除器

       循环引用即在使用双向链表时,若使用shared_ptr则会出现在析构时由于同一块空间有两个对象指向,且对象两两之间相互指向,故在析构时两对象都在等对方的_pCount减为一,从而一直到最后对象都没有析构

shared_ptr<Node>cur(new Node(1));
shared_ptr<Node>next(new Node(1));
cur->_next=next;
next->_prev=cur;

shared_ptr的定制删除器

template<class T,class D>
class ShartedPtr
{
public:
	//构造函数
	ShartedPtr(T* ptr)
	:_ptr(ptr)
	, _pCount(new int(1))
	{
	}
	//构造函数的一个重载
	ShartedPtr(T* ptr,D del)
		:_ptr(ptr)
		, _pCount(new int(1))
		, _del(del)
	{
	}
	//拷贝构造
	ShartedPtr(const ShartedPtr<T,D>&sp)
		:_ptr(sp._ptr)
		, _pCount(sp._pCount)
	{
		++(*_pCount);
	}
	//赋值
	ShartedPtr&operator = (ShartedPtr<T,D>sp)
	{
		swap(_ptr, sp._ptr);
		swap(_pCount, sp._pCount);

		return *this;
	}
	//重载*
	T &operator*()
	{
		return *_ptr;
	}
	//重载->
	T *operator->()
	{
		return _ptr;
	}
	//析构函数
	~ShartedPtr()
	{
		Release();
	}
protected:
	void Release()
	{
		if (--(*_pCount) == 0)
		{
			_del( _ptr);
			delete _pCount;
		}
	}
private:
	T* _ptr;
	int *_pCount;
	D _del;
};
struct DefaultDel
{
	void operator()(void* ptr)
	{
		delete ptr;
	}
};
struct Free
{
	void operator()(void* ptr)
	{
		free(ptr);
	}
};
//struct Fclose
//{
//	void operator()(void* ptr)
//	{
//		fclose(FILE*(ptr));
//	}
//};
int main()
{
	ShartedPtr<int, DefaultDel>sp1(new int(1));
	ShartedPtr<int, Free>sp2((int*)malloc(sizeof(int)));

}

   ps:仿函数的介绍

    仿函数就是使一个类使用看上去像一个函数,其实现就是类中实现一个operator().这个类就有了类似函数的行为。

struct Free
{
                 void operator()(void *ptr)
                {
                                free( ptr);
                }
};
void Testsharedptr()
{
int *p1=(int*)malloc(sizeof(int)*10);
shared_ptr<int>sp1(p1,Free());//在使用完后自动释放p1
}


本文出自 “无以伦比的暖阳” 博客,请务必保留此出处http://10797127.blog.51cto.com/10787127/1760220

以上是关于shared_ptr的作用的主要内容,如果未能解决你的问题,请参考以下文章

c++11智能指针(一) shared_ptr

boost::shared_ptr与定制删除器

提升 shared_ptr 和派生类

C++智能指针的作用,模拟实现auto_ptr,scoped_ptr,shared_ptr

从另一个 shared_ptr 的原始指针生成 shared_ptr

shared_ptr智能指针为什么循环引用会出问题