天天看点

Cocos2dx 小技巧(二)单例

我们的主题是:有些技巧你不知道不要紧,但知道后会很牛逼。

-----------------------------------------------------------------------------------------------------------

首先来说下什么是单例:

单例模式是设计模式中最简单的形式之一。这一模式的目的是使得类的一个对象成为系统中的唯一实例。单例模式的要点有三个;一是某个类只能有一个实例;二是它必须自行创建这个实例;三是它必须自行向整个系统提供这个实例。

上面这段话讲的很严谨,很抽象有木有!没错,你猜对了,它来自百度百科...下面我用简短、无科学依据的语言组织一下:

假如你是个一个男的,但是你私生活不能自理:不会煮饭,洗衣服,穿的衣服永远都no fashion。这时候你需要什么?没错,需要一个女朋友!但这个女朋友你该怎么“使用”呢?给你以下两种选择:

1、要洗衣服的时候“创建”一个女朋友(也就是去找一个女朋友),洗完后将女朋友甩了;当你要做饭,继续“创建”一个女朋友,做完后甩掉;甚至是当你需要满足某种不可告人的需求时,你需要“创建”一个女朋友...然后..

2、找一个可以过一辈子的女朋友,永远在一起,你若不离,她便不弃!想怎么用就怎么用,省去了相亲等一系列麻烦!

以上两种方法虽然都可以让你告别你的右手,但是第一种方法的前提条件太夸张了:你要是一个高富帅,像博主这样的。呵呵。呵呵

所以,还是选第二种吧,也就是我们所说的单例模式,你想甩也甩不掉。

好了,言归正传,为什么我们要用单例来设计游戏呢,参考这句话:

众所周知,游戏开发中离不开游戏数据保存和加载。这些数据包括关卡数据、游戏进行中的状态数据等。这样一些信息很多游戏模块中都需要访问,所以可以为之设置一个单例对象。我武断地认为,客户端游戏开发中,至少需要一个单例对象。因为一个全局的访问点可以方便很多对象之间的交互。

-----------------------------------------------------

下面介绍单例的简单使用方法:

1、声明一个类:

class TestSingleton : public cocos2d::Layer
{
public:
	static TestSingleton* getInstance();//创建一个全局访问点,例如我们常用的Director::getInstance()就是这样一个单例
	void test();//测试单例时用到。

private:
	static TestSingleton* m_singleton;

};
           

2、定义实现:

TestSingleton* TestSingleton::m_singleton = nullptr;//m_singleton指向空指针

TestSingleton* TestSingleton::getInstance()
{
	//判断m_singleton是否已被实例化, 如果没有,将之实例
	if(nullptr == m_singleton)
	{
		m_singleton = new TestSingleton();//
	}
	return m_singleton;
}

void TestSingleton::test()
{
	CCLOG("test testSingleton success~~");
}
           

3、测试单例

我直接在HelloWorld这里测试。代码如下:

bool HelloWorld::init()
{
	TestSingleton::getInstance()->test();//调用TestSingleton里的test(),看控制台是否输出success
}
           

很明显是成功的,我就不贴结果啦。

4、释放

单例这东西用起来一定要谨慎谨慎再谨慎,如非万不得已,尽可能别用吧。因为大家要考虑这么一个问题:单例是什么时候被释放的?按目前实现的方法,单例是直到游戏退出时才释放的!所以当游戏中使用过多的单例是十分浪费空间,或者说根本不能容忍的!

在网上查找了一些释放单例的办法。这篇博客总结了挺多,大家可以按自身申请使用。http://blog.csdn.net/gogogo/article/details/7009862

因为Director也使用到了单例,我看了下,它是在析构函数里将单例置NULL。然后再调用Director::getInstance()->end();后把释放标志_purgeDirectorInNextLoop=true;然后在下一帧执行Director::purgeDirector()方法。其中最后的release()才释放内存。

继续阅读