在cocos2dx中存在不少的單例,雖然單例的設計模式引起不少弊端。我們使用單例目的就是獲得全域性的唯一乙個物件,來做一些事情,那麼什麼時候用單例什麼時候不用單例呢。我覺得乙個是從道理上來說,單例在全域性應該是唯一的,比如cocos2dx中的導演類,乙個遊戲應該只有乙個導演去完成一些功能,還有就是當你需要在乙個類中初始化乙個需要設定為單例的物件,為這個物件的成員變數賦值,當在另一類中的時候,我們需要取得這個物件中的成員變數的值的時候,這樣就設計成單例的,雖然通過其他的方法也可以完成任務,我覺得設計成單例還是比較方便的,下面給出單例的模板。
//單例模板
template
class singleton
; //將建構函式私有或保護
private:
static t* iinstance; //存物件
};template
t* singleton::iinstance = null;
template
t* singleton::getinstance()
return iinstance;
}template
void singleton::freeinstance()
}
如上的這種寫法在程式中的時候你可以用具體的資料型別來代替
,但是思路需要按照模板提供的這個思路來寫。
如果你的程式中有多個類想要設定為單例類,而同樣的**不想重複編寫,我們就需要繼承這個模板類,然後做一些操作,下面給出我在摸索過程中的一種方法,這種方法是不能完成任務的,但是你可以知道為什麼會引出最終的那種方法了。
class myclass:public singleton
;
int getage();
protected:
private:
int m_iage;
//將建構函式私有,防止產生其他物件
myclass(){};
};
myclass *c = myclass::getinstance();
c->setage(10);
cout << c->getage() << endl;
程式執行的時候出錯了,因為我們將myclass的建構函式私有了,在單例模板類中,iinstance=new t();這句話是無法通過的,因為在乙個類外是無法訪問該類的私有成員的。如果我們將myclass的建構函式宣告為public的,則類外也就可以宣告物件了,這和單例的初衷又相悖了。所以利用c++的知識,我們需要將這個單例模板類宣告為myclass類的友元類,這樣的話就可以做到了,現在我將myclass類修改一下,新增一下**
friend class singleton; //將單例模板設定為myclass的友元類
ccnotificationcenter事件***也好,觀察者模式也罷,這個東西的用處就是用在倆個類通訊的時候,乙個類用來傳送訊息,乙個類用來接收訊息。其實這個東西的用處是非常大的,舉個例子吧。比如一片草地,會在不同的季節反應出不同的狀態,春天的時候草長了出來,都是綠的,夏天的時候草長的更高了,秋天的時候又會變顏色,有篇部落格事件驅動,你想象不到的強大。下面我來說說怎麼用這個東西,以及用的時候要注意的一些問題。
1
//將訊息名定義在乙個標頭檔案中
2
#ifndef _notification_h_
3
#define _notification_h_
4
5
#define my_notification "hello"
6
7
#endif
ccnotification採用了單例的設計模式,使用函式addobserver來監聽訊息。這段**我寫在了init中。
1
//第乙個引數是監聽訊息的物件,第二個引數是訊息發來的時候呼叫的函式,第三個引數訊息的名字
2
//第四個引數訊息體
3
ccnotificationcenter::sharednotificationcenter()->addobserver(
this
,
4
callfunco_selector(testscene::getnotification),my_notification,null);
1
//監聽訊息的函式
2
void
testscene::getnotification(ccobject * object)
3
接下來就是使用post來傳送訊息了。
1
void
helloworld::menuclosecallback(ccobject* psender)
2
釋放訊息一般寫在onexit()函式中,就是誰監聽訊息,誰釋放訊息。
檢視源**
列印幫助
1
void
testscene::onexit()
2
二段構建模式
大家都知道在c++中我們一般在建構函式中為物件分配記憶體空間然後初始化成員變數,比如我們呼叫了new某個東西,那麼在堆上會先為物件分配記憶體空間,然後呼叫建構函式,在建構函式中完成一些初始化的工作。而二段構建模式就是將記憶體空間的分配和初始化分開來完成,然後呼叫乙個靜態方法來返回這個物件。就拿cocos2dx中的sprite類來說吧,當我們呼叫sprite::create()的時候內部先使用new來分配記憶體空間,然後呼叫init方法來初始化一些變數的設定。所以cocos2dx中的二段構建模式就是將new分配記憶體空間和init初始化內容分開來處理,而不是c++傳統的做法在建構函式中初始化變數。
1
sprite* sprite::create()
2
12
cc_safe_delete(sprite);
13
return
nullptr;
14
}
上邊就是使用二段構建模式的過程,sprite首先呼叫new來分配記憶體空間,然後呼叫init函式來完成初始化的工作,順帶還做了記憶體管理的工作,最後返回初始化好的物件。所以看了sprite的create方法的實現,我們也知道了應該怎麼使用這個二段構建模式了吧。
第二個問題是為什麼要這麼用,對於c++程式設計師來說初始化工作不都是在建構函式中完成的嗎,cocos中為何要這麼做呢?這裡引述一下王哲的話:「其實我們設計二段構造時首先考慮其優勢而非相容cocos2d-iphone. 初始化時會遇到資源不存在等異常,而c++建構函式無返回值,只能用try-catch來處理異常,啟用try-catch會使編譯後二進位制檔案大不少,故需要init返回bool值。symbian, bada sdk,objc的alloc + init也都是二階段構造」。現在大家明白了吧,相容cocos2d-iphone是乙個原因,另乙個重要的原因是建構函式沒有返回值啊,如果載入資源的時候不存在怎麼辦,所以初始化的工作寫在init函式中,這個函式返回的bool值用來判斷是否初始化成功。使用這種方法還可以強化設計,想想自己寫**的時候是不是因為沒有初始化某個成員變數導致了bug,這樣做就是提醒你記得要在init中初始化成員變數。通過create靜態函式返回的這個物件也實現了cocos2dx中的記憶體管理,就不用我們自己麻煩了。還有乙個原因是在c++的建構函式中是不能呼叫虛函式的,為了呼叫虛函式來完成一些功能就要寫在init函式中。
以上就是二段構建模式的說明了,在我們寫cocos程式的時候其實不知不覺就已經在使用這個構建模式了,想一下我們乙個類繼承了layer,然後使用了巨集create_func(),這不就是create靜態方法嗎,在init函式中完成了初始化,整個過程就是在用這種設計模式!
Cocos2d x的設計模式
單例模式 單例模式的定義是產生乙個類的唯一例項,但js本身就是一種 無類 語言,很多講就是設計模式的文章把 當成乙個單例來使用也勉強說的通,因為js生成物件的方式有很多種。簡單工廠模式 簡單工廠模式是由乙個方法來決定到底要建立哪個類的例項,而這些例項經常都擁有相同的介面,這種模式主要用於在所例項化的...
Cocos2D X設計模式 組合模式
在開始挖掘cocos2d x裡面的組合模式之前,我先武斷地下個結論 幾乎所有與gui相關的框架設計都應用了組合設計模式 ps 大家注意我的用詞,是 幾乎所有 給自己留條後路,哈哈 說到樹,我們馬上就會想到樹根,樹幹和樹葉。一棵樹一般只包含乙個根,若干樹幹和大量的葉子。同時,樹幹長在樹根上,樹葉長在樹...
cocos2dx中的設計模式
1.二段構建模式 大家都知道在c 中我們一般在建構函式中為物件分配記憶體空間然後初始化成員變數,比如我們呼叫了new某個東西,那麼在堆上會先為物件分配記憶體空間,然後呼叫建構函式,在建構函式中完成一些初始化的工作。而二段構建模式就是將記憶體空間的分配和初始化分開來完成,然後呼叫乙個靜態方法來返回這個...