衝突判定などで、直接該当クラスを呼び出すのではなく、親クラスを呼び出して、同じメソッドを利用する。 そのメソッドは子クラスごとに違っている。そのような処理をしたくて、結構悩んでいました。 今回は、この仮想関数についてのメモを簡単に記述します。
例えば、こんような感じ「親クラス」と「小クラス」があります。 [c]
//親クラス class ParentClass : public cocos2d::CCNode{
private:
void hitPlayer();
};
//子クラス class ChildClass : public ParentClass{
private:
void hitPlayer();
};
[/c]
「子クラス」が多くなると個別に識別するのがメンドクサイので、「親クラス」を呼び出して共通のメソッド(今回はhitPlayer())を呼び出したい。 この時のメソッドの中身は「子クラス」ごとに違う。 [c] if(dynamic_cast<ParentClass*>(obj)){
if (objRect.intersectsRect(playerRect)) {
ParentClass *_obj = (ParantClass*)obj;
_obj->hitPlayer();
}
[/c]
ただ上記の場合は、「子クラス」のメソッドを呼び出してしまうので、個別の処理ができない。
仮想関数 virtual を使う
初期化メソッド(init())で、virtualを頭につけているのは知っていたのですが、これがどのような意味をなしているのかよくわかっていませんでした。 実は、これを「親クラス」に設置しておけば、たとえ「親クラス」としてメソッドが呼び出されても、本来のクラスである「子クラス」のメソッドが呼び出されるようになるのです。 [c]
//親クラス class ParentClass : public cocos2d::CCNode{
private:
//仮想関数として定義しておく
virtual void hitPlayer();
};
//子クラス class ChildClass : public ParentClass{
private:
void hitPlayer();
};
[/c]
これで、「親クラス」のメソッドを呼び出しても、「子クラス」に同じメソッドがあれば、そちらを呼び出してくれます。
cocos2dx 現在の疑問点
C++で、objective-cでできていたことで、現在できていないのは、オブジェクトからクラスを導きだす方法です。 例えば、オブジェクトのプロパティにNSString型のクラス名を記載して、そのこらインスタンスを作成する。こういったことが、cocos2dでできていました。
[c]
//プロパティにあるNSString型からクラスを作成 CCNode item; Class cla = NSClassFromString([[props valueForKey:@"in"] capitalizedString]);
if (cla != nil) {
item = [[cla alloc] init];
}
[/c]
現在は、いちいちif文を利用して、個別にクラスを判別してオブジェクトを生成しています。 [c]
//こんな感じです。 if (strcmp(classname, "block") == 0) {
Block*obj = Block::create();
this->addChild(obj,5);
} [/c]
これだと、コードが長くなり効率が悪いなと考えていますが、良い方法がないので仕方なくこうしてます。 何か良い方法はないのでしょうか? もし、何か良い方法があれば教えて欲しいです。