所谓定制删除器,就是向目标模板提供一个可以自由选择析构的接口,这样做的好处就是可以使智能指针模板不再只能单独管理内存,我们还可以用它管理文件指针之类的东西。其实现方法有两种,这里我们以share指针为例。

    1.传递一个类的模板参数并给出缺省值,模板中将该类设定为成员变量,通过该类(删除类)的实例化,调用类中所存的删除方法进行删除。

    代码如下:

#include<iostream>
template <class T>
struct Del
{
	void operator ()(const T*ptr)
	{
		if (ptr)
		{
			delete ptr;
		}
	}
};
struct Free
{
	void operator() (void* ptr)
	{
		cout << "free:" << ptr << endl;
		free(ptr);
	}
};
struct Close
{
	void operator()(void *ptr)
	{
		cout << "Close" << endl;
		fclose((FILE*)(ptr));
	}
};

template<class T, class Deleter = Del<T>>
class SharedPtr
{
public:
	SharedPtr(T* ptr)
		:_ptr(ptr)
		, _pCount(new long(1))
	{}

	SharedPtr(T* ptr, Deleter del)
		:_ptr(ptr)
		, _pCount(new long(1))
		, _del(del)
	{}

	~SharedPtr()
	{
		_Release();
	}

	SharedPtr(const SharedPtr<T>& sp)
		:_ptr(sp._ptr)
		, _pCount(sp._pCount)
	{
		++(*_pCount);
	}

	//SharedPtr<T>& operator=(const SharedPtr<T>& sp)//传统写法
	//{
	//	if (this != &sp)
	//	{
	//		this->_Release();		
	//		_pCount = sp._pCount;
	//		_ptr = sp._ptr;
	//		++(*_pCount);
	//	}

	//	return *this;
	//}

	SharedPtr<T>& operator=(SharedPtr<T> sp)
	{
		swap(_ptr, sp._ptr);
		swap(_pCount, sp._pCount);

		return *this;
	}

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

	T* operator->()
	{
		return _ptr;
	}

	T* GetPtr()
	{
		return _ptr;
	}

	long GetCount()
	{
		return *_pCount;
	}

protected:
	void _Release()
	{
		if (--(*_pCount) == 0)
		{
			//delete _ptr;
			_del(_ptr);
			delete _pCount;
		}
	}

protected:
	T* _ptr;
	long* _pCount;
	Deleter _del;
};

   测试用例如下:

void Test2()
{
	SharedPtr<int> sp1(new int(1));
	SharedPtr<int, Free> sp2((int*)malloc(sizeof(int)* 10), Free());
	SharedPtr<FILE, Close>sp3 = std::fopen("Test.txt", "w");
}

     2.在智能指针的模板中,添加函数指针变量,通过构造函数确定所传递的函数指针,用该指针所指向的方法进行删除。

代码如下:

void free()
{
	cout << "void free()" << endl;
}
void del()
{
	cout << "void del()" << endl;
}
void close()
{
	cout << "void close()" << endl;
}

template<class T>
class SharedPtr
{
public:
	SharedPtr(T* ptr)
		:_ptr(ptr)
		, _pCount(new long(1))
	{}

	SharedPtr(T* ptr, void(*p)())
		:_ptr(ptr)
		, _pCount(new long(1))
		, del(p)
	{	}

	~SharedPtr()
	{
		_Release();
	}

	SharedPtr(const SharedPtr<T>& sp)
		:_ptr(sp._ptr)
		, _pCount(sp._pCount)
	{
		++(*_pCount);
	}

	SharedPtr<T>& operator=(SharedPtr<T> sp)
	{
		swap(_ptr, sp._ptr);
		swap(_pCount, sp._pCount);

		return *this;
	}

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

	T* operator->()
	{
		return _ptr;
	}

	T* GetPtr()
	{
		return _ptr;
	}

	long GetCount()
	{
		return *_pCount;
	}

protected:
	void _Release()
	{
		if (--(*_pCount) == 0)
		{
			del();
			delete _pCount;
		}
	}

protected:
	T* _ptr;
	long* _pCount;
	void(*del)();	
};

    测试用例如下:

void Test1()
{
	void(*p)();
	int a = 0;
	SharedPtr<int>p1(&a, close);
}

    如有什么不足或疑问,希望留言一起探讨,如有不择也希望批评指正。