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
}
时间: 2024-12-08 10:08:41

boost::shared_ptr与定制删除器的相关文章

【智能指针的延伸】两种定制删除器的实现方法

所谓定制删除器,就是向目标模板提供一个可以自由选择析构的接口,这样做的好处就是可以使智能指针模板不再只能单独管理内存,我们还可以用它管理文件指针之类的东西.其实现方法有两种,这里我们以share指针为例.   1.传递一个类的模板参数并给出缺省值,模板中将该类设定为成员变量,通过该类(删除类)的实例化,调用类中所存的删除方法进行删除. 代码如下: #include<iostream> template <class T> struct Del { void operator ()(

智能指针(模拟实现auto_ptr,shared_ptr,scooeptr 以及定制删除器c++ 实现)

#define  _CRT_SECURE_NO_WARNINGS #include<iostream> using namespace std; template<class T> class Auto_ptr { public:  Auto_ptr(T* _x) :x(_x)  {}  Auto_ptr(Auto_ptr<T> &s) :x(s.x)  {   s.x = NULL;  }  Auto_ptr& operator=(Auto_ptr&l

c++ 之定制删除器的代码实现(使用仿函数)

template<class T> struct Del {  void operator()(const T* ptr)  {   cout << "Del" <<ptr<< endl;   delete ptr;  } }; template<class T> struct FFF {  void operator()(const T* ptr)  {   cout << "delete[]"

【C++】智能指针shared_ptr 定位删除器(仿函数)

智能指针shared_ptr 用引用计数实现看起来不错,但却存在问题. 1.引用计数更新存在着线程安全: 2.循环引用--使用一个弱引用智能指针(weak_ptr)来打破循环引用(weak_ptr不增加引用计数) 3.定置删除器和空间分配器 比如打开一个文件的关闭,用malloc开辟出来的空间,用引用计数实现会出现问题. 对改变引用计数时加锁可以解决引用计数更新存在着线程安全. 循环引用问题 #include<iostream> using namespace std; #include<

C++智能指针剖析(下)boost::shared_ptr&amp;其他

1. boost::shared_ptr 前面我已经讲解了两个比较简单的智能指针,它们都有各自的优缺点.由于 boost::scoped_ptr 独享所有权,当我们真真需要复制智能指针时,需求便满足不了了,如此我们再引入一个智能指针,专门用于处理复制,参数传递的情况,这便是如下的boost::shared_ptr. boost::shared_ptr 属于 boost 库,定义在 namespace boost 中,包含头文件#include<boost/smart_ptr.hpp> 便可以使

shared_ptr循环引用&定置删除器

shared_ptr虽然方便,但是它有着一个致命的缺陷就是循环引用问题,因为shared_ptr本身并没有能力解决这个问题,所以我们又引入了弱指针weak_ptr来辅助shared_ptr解决这个问题. 那么循环引用又是什么场景? 举个栗子: 假设现在我们要创建一个双向整形链表,但是这个链表的指针域全部都用shared_ptr维护: struct Node { int _data; shared_ptr<Node> _next; shared_ptr<Node> _prev; }

shared_ptr(下) 删除器

1.shared_ptr中的px出现原因 方便对其数据空间的管理,取值和获取地址将极大的方便我们的操作. 2.解决析构函数 避免内存空间的泄漏.new出来的空间都没有释放掉! 释放拥有权靠的是引用计数. ~shared_count(){      if(pi){  //判断所指父类是否为空         pi->release(); //释放new出来的对象和外部new出来的空间     } } /////////////////////////////////////////////////

智能指针的模拟实现shared_ptr 循环引用 定置删除器

auto_ptr与scoped_ptr的实现见本人的上篇博客. 三.shared_ptr shared_ptr的实现原理是通过引用计数来实现,只有当引用计数为1时才释放空间,否则只需将引用计数减1.拷贝和赋值将引用计数加1,具体代码如下: template <typename T> class SharedPtr { public: SharedPtr(); SharedPtr(T* ptr); SharedPtr(const SharedPtr<T>& ap); ~Sha

实战c++中的智能指针unique_ptr系列-- unique_ptr的get_deleter方法(自定义删除器)

unique_ptr的成员函数在上一篇博客中几乎全部涵盖,其实还有一个很有踢掉,即std::unique_ptr::get_deleter 字面已经很明显了,就获得deleter: Returns the stored deleter The stored deleter is a callable object. A functional call to this object with a single argument of member type pointer is expected