天天看點

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()才釋放記憶體。

繼續閱讀