⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mysmartptr.h

📁 一个类似于c++ stl中的auto_ptr
💻 H
字号:
/*
 * urong@9#, 2007.08.21
 * 模板类MySmartPtr,在这个模板类实例化的时候,它储存一个裸指针,并且它会在实例析构的时候自动的释放指针所指的内存空间
 * 通过使用一个标识参数来支持不同的类型:单个类、数组
 *										 0		 1	 
 */

#ifndef _MY_SMART_PTR_H_
#define _MY_SMART_PTR_H_

#include <map>

using namespace std;

template<class ResType>
class MySmartPtr{
public:
	//构造函数
	//构造过程中产生新的资源号
	explicit MySmartPtr(ResType* ptr, int ptrType);
	
	//存储right对象所指的资源
	//增加s_mspcToPtrnMap中相应ptrNum对应的mspCount
	MySmartPtr(const MySmartPtr<ResType>& right);

	//删除s_mspcToPtrnMap中的ptrNum
	//如果成功则调用private _releaseRes()释放资源
	~MySmartPtr();

	//赋值操作重载
	//把自己的m_ptr资源释放,而存储right对象所指的资源
	//增加s_mspcToPtrnMap中相应ptrNum对应的mspCount
	MySmartPtr<ResType>& operator= (const MySmartPtr<ResType>& right);

	//*操作重载
	//获得所管理的资源的对象的引用
	ResType& operator*() const;

	//->操作重载
	//获得指向所管理的资源的指针
	ResType* operator->() const;

	//获得指向所管理的资源的指针
	ResType* get();
private:
	//在s_mspcToPtrnMap注册资源ptr,使用相应的ptrNum
	//如果该ptrNum不存在则插入s_mspcToPtrnMap中,并把mspCount置为1
	//如果该ptrNum已经存在,则inc s_mspcToPtrnMap中相应的mspCount
	void registerPtr(int ptrNum);

	//在s_mspcToPtrnMap中查找相应的ptrNum,并返回mspCount值
	int lookupPtr(int ptrNum);

	//删除s_mspcToPtrnMap中相应的ptrNum的内容
	//如果相应的mspCount = 1,则删除,并返回true
	//否则不删除,dec mspCount,并返回false
	bool deletePtr(int ptrNum);

	//产生新的ptrNum
	int newPtrNum();

	//增加mspCount
	int incMspCount(int& mspCount);

	//减少mspCount
	int decMspCount(int& mspCount);

	//释放资源
	//根据不同的ptrType调用不同的资源释放函数
	void _releaseRes();

	//释放单个Object的资源
	void releaseSingleObject();

	//释放数组的资源
	void releaseArray();

	//释放c++标准容器的资源
	//使用标准容器提供的iteratro
	void releaseSTLContainer();

public:
	static const int sc_SINGLE_OBJECT = 0;
	static const int sc_ARRAY = 1;
private:
	//资源指针的类型:单个类、数组、标准容器
	int m_ptrType;

	//存储资源的指针
	ResType* m_ptr;

	//资源号
	int m_ptrNum;

	//资源号与管理相应资源的MySmartPtr对象数量mspCount的映射
	//一旦映射中某个资源号对应的mspCount减到了0,则释放该资源,并把资源号从映射表中删除
	//map<int ptrNum, int mspCount>
	static map<int, int> s_mspcToPtrnMap;

	//资源号最大值
	//当前使用显示构造函数构造的对象所管理的资源号=s_ptrNumtMax+1
	//mspCountMax的初始化值为0
	static int s_ptrNumtMax;
};

template<class ResType>
map<int, int> MySmartPtr<ResType>::s_mspcToPtrnMap = map<int, int>();

template<class ResType>
int MySmartPtr<ResType>::s_ptrNumtMax = 0;

template<class ResType>
MySmartPtr<ResType>::MySmartPtr(ResType* ptr, int ptrType){
	//产生新的资源号
	int ptrNum = newPtrNum();
	m_ptrNum = ptrNum;
	//注册新资源
	registerPtr(ptrNum);

	//存储资源和资源类型信息
	m_ptrType = ptrType;
	m_ptr = ptr;
}

template<class ResType>
MySmartPtr<ResType>::MySmartPtr(const MySmartPtr<ResType>& right){
	//复制私有变量
	this->m_ptr = right.m_ptr;
	this->m_ptrNum = right.m_ptrNum;
	this->m_ptrType = right.m_ptrType;

	//增加mspCount
	registerPtr(this->m_ptrNum);
}

template<class ResType>
MySmartPtr<ResType>& MySmartPtr<ResType>::operator= (const MySmartPtr<ResType>& right){
	//释放m_ptr中的资源
	_releaseRes();

	//复制right到this中
	this->m_ptr = right.m_ptr;
	this->m_ptrNum = right.m_ptrNum;
	this->m_ptrType = right.m_ptrType;
	
	//增加mspCount
	registerPtr(this->m_ptrNum);

	return *this;
}

template<class ResType>
MySmartPtr<ResType>::~MySmartPtr(){
	//删除s_mspcToPtrnMap中的ptrNum
	bool delRes = deletePtr(this->m_ptrNum);

	//如果成功则释放资源
	if(delRes == true){
		_releaseRes();
	}
	//否则do nothing
	else{
		//do nothing
	}
}

template<class ResType>
void MySmartPtr<ResType>::registerPtr(int ptrNum){
	map<int, int>::iterator iter = s_mspcToPtrnMap.find(ptrNum);

	//如果不存在,则insert
	if(iter == s_mspcToPtrnMap.end()){
		s_mspcToPtrnMap.insert(pair<int, int>(ptrNum, 1));
	}
	//否则增加mspCount项
	else{
		incMspCount(iter->second);
	}
}

template<class ResType>
int MySmartPtr<ResType>::lookupPtr(int ptrNum){
	return s_mspcToPtrnMap.find(ptrNum)->second;
}

template<class ResType>
bool MySmartPtr<ResType>::deletePtr(int ptrNum){
	map<int, int>::iterator iter = s_mspcToPtrnMap.find(ptrNum);

	if(iter->second == 1){
		s_mspcToPtrnMap.erase(iter);
		return true;
	}

	//else
	decMspCount(iter->second);
	return false;
}

template<class ResType>
int MySmartPtr<ResType>::newPtrNum(){
	return ++s_ptrNumtMax;
}

template<class ResType>
int MySmartPtr<ResType>::incMspCount(int& mspCount){
	return ++mspCount;
}

template<class ResType>
int MySmartPtr<ResType>::decMspCount(int& mspCount){
	return --mspCount;
}

template<class ResType>
void MySmartPtr<ResType>::_releaseRes(){
	switch(this->m_ptrType){
		case MySmartPtr<ResType>::sc_SINGLE_OBJECT:
			releaseSingleObject();
			break;
		case MySmartPtr<ResType>::sc_ARRAY:
			releaseArray();
			break;
		default:
			//!!
			break;
	}
}

template<class ResType>
void MySmartPtr<ResType>::releaseSingleObject(){
	delete m_ptr;
}

template<class ResType>
void MySmartPtr<ResType>::releaseArray(){
	delete[] m_ptr;
}

template<class ResType>
ResType* MySmartPtr<ResType>::get(){
	return m_ptr;
}

template<class ResType>
ResType& MySmartPtr<ResType>::operator *() const{
	return *m_ptr;
}

template<class ResType>
ResType* MySmartPtr<ResType>::operator ->() const{
	return &**this;
}

#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -