【智能指針的延伸】兩種定製刪除器的實現方法

    所謂定製刪除器,就是向目標模板提供一個能夠自由選擇析構的接口,這樣作的好處就是能夠使智能指針模板再也不只能單獨管理內存,咱們還能夠用它管理文件指針之類的東西。其實現方法有兩種,這裏咱們以share指針爲例。
ios

    1.傳遞一個類的模板參數並給出缺省值,模板中將該類設定爲成員變量,經過該類(刪除類)的實例化,調用類中所存的刪除方法進行刪除。ide

    代碼以下:
函數

#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.在智能指針的模板中,添加函數指針變量,經過構造函數肯定所傳遞的函數指針,用該指針所指向的方法進行刪除。
this

代碼以下:指針

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);
}

    若有什麼不足或疑問,但願留言一塊兒探討,若有不擇也但願批評指正。
內存

相關文章
相關標籤/搜索