首页 > 其他 > 详细

两种用于派生的Singleton模式(以TextureMgr为例)

时间:2015-07-01 23:44:02      阅读:481      评论:0      收藏:0      [点我收藏+]

  Singleton,顾名思义,从字面上来理解就是单例模式,这是C++程序中

常用到的一种设计模式,特别是像文件管理器,纹理管理器这种整个软件

中只需要唯一的实例来管理所有资源时,这种模式的价值便得以体现。

  下面来介绍两种用于派生管理的Singleton模式:

  其中,第一种是Gof版本的Singleton, 其代码如下:

//【Singleton_Gof.h】
#pragma  once

template<typename T>
class Singleton_Gof
{
protected:
	static T* ms_Singleton;
	Singleton_Gof(){assert(!ms_Singleton);}
	~Singleton_Gof(){assert(ms_Singleton);ms_Singleton=NULL;}
private:
	Singleton_Gof(const Singleton_Gof&); //防止构造函数的复制
	Singleton_Gof& operator=(const Singleton_Gof&);

public:
	static T* getSingletonPtr(){if (!ms_Singleton)ms_Singleton = new T();return ms_Singleton;}
	static T& getSingleton(){if (!ms_Singleton)ms_Singleton = new T();return (*ms_Singleton);}
}; 
template<typename T>T* Singleton_Gof<T>::ms_Singleton = NULL;

  其大致上的原理便是在需要初始化时,将静态的Singleton实例指向派生类T对象,

  类似的,还有第二种Singleton, 其代码如下:

//【Singleton.h】
#pragma once
#include <cassert>

template<typename T>
class Singleton
{
private:
	Singleton(const Singleton<T>&);
	Singleton& operator=(const Singleton<T> &);

protected:
	static T* ms_Singleton;
	Singleton(){
	assert(!ms_Singleton);
#if defined( _MSC_VER ) && _MSC_VER < 1200  
		int offset = (int)(T*)1 - (int)(Singleton <T>*)(T*)1;
		ms_Singleton = (T*)((int)this + offset);

#else
		ms_Singleton = static_cast< T* >( this );
#endif
	};
	~Singleton(){assert(ms_Singleton); ms_Singleton = NULL;}
public:	
	static T& getSingleton(){if(!ms_Singleton)new T(); return (*ms_Singleton);}
	static T* getSingletonPtr(){if(!ms_Singleton)new T(); return ms_Singleton;}
};

template<typename T>T* Singleton<T>::ms_Singleton = NULL;

        Singleton()里的代码在OGRE和《游戏编程精粹》都出现过,这里涉及VC编译器的内存对齐,就不详细讲解了,

        然后我们便可以利用上面的Singleton()代码派生出一个纹理管理器来,我这里粗略写了下:

//【TextureMgr.h】
#include <string>
#include <map>
#include <iostream>
#include "Singleton.h"
#include "Singleton_Gof.h"
using namespace std;

//Texture
class Texture
{
private:	
	string m_Name;
public:
	Texture(const string name):m_Name(name){load();};
	~Texture(){unload();}
	const string& getName()const {return m_Name;}
	bool load(){cout<<"加载了一张纹理:"+m_Name<<endl;return true;}
	bool unload(){cout<<"从资源中清除一张纹理:"+m_Name<<endl;return true;}
	void doSomeThing(){cout<<"对纹理:"+m_Name+",进行了某些操作"<<endl;}
};

typedef std::map<string, Texture*> texMap;
typedef texMap::iterator texMapIter;
#define SAFE_DELETE(p) {if(p){delete p;p=NULL;}}


//TextureMgrBase
class TextureMgrBase
{
	texMap m_TiMap;
public:	
	Texture* getTexture(const string name)
	{
		texMapIter iter = m_TiMap.find(name);
		if(iter == m_TiMap.end())
		{
			Texture* tex = new Texture(name);
			m_TiMap.insert(std::make_pair(name, tex));
			return tex;
		}
		else
		{
			return iter->second;
		}
	}	
	TextureMgrBase(){cout<<"TextureMgrBase constructor"<<endl;}
	~TextureMgrBase(){		
		for(texMapIter iter = m_TiMap.begin();iter!=m_TiMap.end();iter++)
		{
			SAFE_DELETE(iter->second);
		}
		cout<<"TextureMgrBase destructor"<<endl;
	}
};

//TextureMgr
class TextureMgr:public TextureMgrBase, public Singleton<TextureMgr>{
public:
	TextureMgr(){cout<<"TextureMgr constructor"<<endl;}
	~TextureMgr(){cout<<"TextureMgr destructor"<<endl;}
};
//TextureMgrGof
class TextureMgr_Gof:public TextureMgrBase, public Singleton_Gof<TextureMgr_Gof>{
public:
	TextureMgr_Gof(){cout<<"TextureMgr_Gof constructor"<<endl;}
	~TextureMgr_Gof(){cout<<"TextureMgr_Gof destructor"<<endl;}
};

因为加了断言保证只有一次调用,所以就能全局唯一了,因此我们便可以如下来使用这纹理管理器(需要手动删除):

//【main.cpp】
#include "TextureMgr.h"
#include<iostream>
using namespace std;

#define  g_TexMgr TextureMgr::getSingleton()
#define  g_TexMgr_Gof TextureMgr_Gof::getSingleton()

int main(char argc, char* argv[])
{
	//TextureMgr
	Texture* tex1 = g_TexMgr.getTexture("纹理1");
	Texture* tex2 = g_TexMgr.getTexture("纹理2");
	Texture* _tex1 = g_TexMgr.getTexture("纹理1");
	cout<<tex1->getName()<<endl;
	cout<<tex2->getName()<<endl;
	cout<<_tex1->getName()<<endl;
	tex1->doSomeThing();
	tex2->doSomeThing();
	_tex1->doSomeThing();		
	delete &g_TexMgr;
	cout<<endl;

	//TextureMgr_Gof
	Texture* tex3 = g_TexMgr_Gof.getTexture("纹理3");
	Texture* tex4 = g_TexMgr_Gof.getTexture("纹理4");
	Texture* _tex3 = g_TexMgr_Gof.getTexture("纹理3");
	cout<<tex3->getName()<<endl;
	cout<<tex4->getName()<<endl;
	cout<<_tex3->getName()<<endl;
	tex1->doSomeThing();
	tex2->doSomeThing();
	_tex3->doSomeThing();		
	delete &g_TexMgr_Gof;

	system("pause");
	return 0;
}

得到的最终结果如下:

技术分享

版权声明:本文为博主原创文章,未经博主允许不得转载。

两种用于派生的Singleton模式(以TextureMgr为例)

原文:http://blog.csdn.net/beyond_ray/article/details/46714909

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!