我不擅长C ++(但我熟悉OOP / Java),但我必须为我的C ++类创建一个游戏。我想设置一种类似于用ActionScript编写的Flash游戏的游戏引擎。
我写了这两个类,其中Actor
表示基类(可能是抽象的),Player
应该实际实现它。
问题在于我希望避免函数addEventListener
和handle
中重复的代码并重新声明_handlerMap
,因为我想实现数据隐藏等等。
我想问题是,_eventMap
应该包含可以更改类handler
和Actor::*handler
的{{1}}值。有可能吗?
Player::*handler
我希望可以将播放器声明为:
class Actor {
protected:
typedef void(Actor::*handler)(Event);
map<int, handler> _handlerMap;
public:
virtual void addEventListener(int ID, handler h) {
_handlerMap.insert(std::make_pair(ID, h));
};
virtual void handle(int ID) {
handler h = _handlerMap[ID];
Event e;
if (h)
(this->*h)(e);
}
virtual void onUpdate(Event e) {
cout << "Actor::onUpdate()" << endl;
};
};
class Player : public Actor {
typedef void(Player::*handler)(Event);
map<int, handler> _handlerMap;
public:
void addEventListener(int ID, handler h) {
_handlerMap.insert(std::make_pair(ID, h));
};
void handle(int ID) {
handler h = _handlerMap[ID];
Event e;
if (h)
(this->*h)(e);
}
void onKeydown(Event e) {
cout << "Player::onKeyDown()" << endl;
};
};
我希望你明白。
答案 0 :(得分:2)
你需要这样的东西(未经测试):
class Dispatcher {
public:
virtual void dispatchEvent(Event*) = 0;
};
template <class C>
class DispatcherImpl : public Dispatcher
{
typedef void(C::*handler)(Event* e);
std::map<int, handler> _handlerMap;
C* _owner;
public:
DispatcherImpl (C* c) : _owner(c) {}
addEventListener(int ID, handler h) {
_handlerMap.insert(std::make_pair(ID, h));
}
void dispatchEvent(Event*)
{
handler h = handlerMap[e->id];
if (h) (_owner->*h)(e);
}
}
现在让演员的每个类型T
拥有一个DispatcherImpl<T>
,然后你就完成了。您也可能有例如Player
继承自DispatcherImpl<Player>
。
答案 1 :(得分:0)
你怎么看待这个? (Dispatcher与上面的DispatcherImpl相同)
template <class T>
class Entity {
T *_instance;
Dispatcher<T> *_dispatcher;
public:
Entity() {
_instance = new T();
_dispatcher = new Dispatcher<T>(_instance);
}
};
class Actor {
//attirbutes and methods
};
class Player : public Actor {
//attirbutes and methods
};
仅使用它:
Entity<Actor> *actor = new Entity<Actor>();
Entity<Player> *player = new Entity<Player>();
actor->getDispatcher()->addEventListener(0, &Actor::foo);
player->getDispatcher()->addEventListener(1, &Player::bar);
player->getDispatcher()->addEventListener(0, &Actor::foo); //inheritance