Edited at

CREATE_FUNCマクロに引数を持たせるには(cocos2d-x)

More than 3 years have passed since last update.


CREATE_FUNCマクロが引数を持てない問題

リファレンスカウンタの利用の為の機構をお手軽に提供するCREATE_FUNCマクロですが、このマクロを使うと、引数の無いcreate関数になってしまいまして。

というのも、CREATE_FUNCマクロの実装を見れば、その理由も解決法もスパっと分かります。

マクロは闇だからって忌避していては何も始まりません。

#define CREATE_FUNC(__TYPE__) \

static __TYPE__* create() \
{ \
__TYPE__ *pRet = new __TYPE__(); \
if (pRet && pRet->init()) \
{ \
pRet->autorelease(); \
return pRet; \
} \
else \
{ \
delete pRet; \
pRet = NULL; \
return NULL; \
} \
}

あ〜はいはい。

こう書き換えれば分かり易いはず。

改行を適用する為のスラッシュや、命名規則のアンダースコアなどを取り除いて。

 static TYPE* create(){

TYPE* pRet = new TYPE();

if(pRet && pRet->init()){
pRet->autorelease();
return pRet;
}
else{
delete pRet;
pRet = NULL;
return NULL;
}
}

めっちゃ簡単ですね。

マクロで受け取った引数の文字列を弄って関数を生成してるんですが

そのやってる内容は

①ポインタの宣言

②動的生成

③メモリ確保、初期化の可否チェック

④cocos2d::Refに定義されてるリファレンスカウンタ適用のautorelease関数適用

⑤アドレスを返す(③で失敗した場合はNULLを返す)

ってだけです。


じゃあcreateとinitに引数持たせるだけじゃん

じゃ、引数付きのcreate関数を作ればどうすればいいかってのは

③の、初期化...即ちinit関数を引数付きにするだけですね。

というわけで例えばint変数1つを引数に取るcreateを定義するには

マクロの存在は忘れて

 static MYCLASS* create(int n){

MYCLASS* pRet = new MYCLASS();

if(pRet && pRet->init(n)){
pRet->autorelease();
return pRet;
}
else{
delete pRet;
pRet = NULL;
return NULL;
}
}

あとは、init関数をint引数持ちのを定義するだけ!

簡単!

virtual bool init(int); //継承の可能性を考慮し仮想化

//後は適当に定義()

あ、init関数では親クラスのinitを呼び出すことを忘れないでくださいね!

CREATE_FUNCを使おうとしてるってことは、何かしら継承をしてるんでしょう?

例えばcocos2d::Spriteを継承したクラスでinitを定義する時は

bool MYCLASS::init(std::string file_name,type my_arg){

if(!Sprite::initWithFile(filePath))return false;

//my_argに関する処理

return true;
}

みたいな感じですかね。

これくらいのことは、わざわざQiitaに書かなくてもいいかもしれませんが

マクロの定義を見たくない!でもCREATE_FUNCがよくわからん!って人が多そうなので。