C++;-成员函数的多态指针 我不擅长C++(但我熟悉OOP/java),但我必须为我的C++类创建一个游戏。我想设置一种游戏引擎,就像用ActionScript编写的Flash游戏一样
我写了这两个类,其中C++;-成员函数的多态指针 我不擅长C++(但我熟悉OOP/java),但我必须为我的C++类创建一个游戏。我想设置一种游戏引擎,就像用ActionScript编写的Flash游戏一样,c++,function,pointers,C++,Function,Pointers,我写了这两个类,其中Actor是一个基类(可能是抽象的),而Player应该实际实现它 问题是,我希望避免函数addEventListener和handle中的重复代码,并重新声明\u handlerMap,因为我希望实现数据隐藏等功能 我想,问题是\u eventMap应该包含处理程序值,这些值可以更改类参与者::*handler和玩家::*handler。可能吗 class Actor { protected: typedef void(Actor::*han
Actor
是一个基类(可能是抽象的),而Player
应该实际实现它
问题是,我希望避免函数addEventListener
和handle
中的重复代码,并重新声明\u handlerMap
,因为我希望实现数据隐藏等功能
我想,问题是
\u eventMap
应该包含处理程序
值,这些值可以更改类参与者::*handler
和玩家::*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;
};
};
我希望您能理解。您需要这样的东西(未经测试):
类调度器{
公众:
虚拟无效dispatchEvent(事件*)=0;
};
模板
类DispatcherImpl:公共调度器
{
typedef void(C::*处理程序)(事件*e);
标准::地图handlerMap;
业主;
公众:
DispatcherImpl(C*C):_所有者(C){}
addEventListener(整数ID,处理程序h){
_插入(std::make_pair(ID,h));
}
无效调度事件(事件*)
{
handler h=handlerMap[e->id];
若(h)(业主->*h)(e);
}
}
现在,让参与者的每种类型都拥有一个DispatcherImpl,您就都准备好了。例如,您还可以从
DispatcherImpl
继承Player
,您对此有何看法?(调度器与上面的DispatcherImpl相同)
模板
类实体{
T*_实例;
调度员*\u调度员;
公众:
实体(){
_实例=新的T();
_dispatcher=新的dispatcher(\u实例);
}
};
班级演员{
//态度和方法
};
班级演员:公共演员{
//态度和方法
};
使用它只是:
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
Entity*actor=newentity();
实体*player=新实体();
actor->getDispatcher()->addEventListener(0,&actor::foo);
player->getDispatcher()->addEventListener(1,&player::bar);
player->getDispatcher()->addEventListener(0,&Actor::foo)//遗产
是否允许Actor
的其他实例注册处理程序?(即,addEventListener
是否必须是公共成员?)“我想问题是\u eventMap
”->你的意思是\u handlerMap
?我能想到的最简单的解决方案是使用std::function
和std::bind
,可在C++11中使用。dispatchEvent
必须返回某些内容,以便在Player
中没有用于此事件的特殊处理程序的情况下,例如让Player
将事件传递给Actor
。此外,我宁愿使用map::find
而不是map::operator[]
来检查映射中是否存在元素。@DyP:绝对不存在。玩家
是演员
。您还想传递给哪个Actor
?至于map::find
,当然可以使用它。此代码段完全是伪代码,不能按字面意思使用。您的意思是只有派生类型应该继承自DispatcherImpl
?我想你的意思是演员也应该从中派生出来;在这种情况下,您必须从dispatchEvent
返回bool
,以指示事件id是否已在当前\u handlerMap
中找到,或者是否应将其传递给基类的调度程序进行处理。@DyP:Player调度程序具有参与者的所有功能。不需要锁链。我试过了,但没法用。新的“Player”类现在有一个“DispatcherImpl”成员,我在Player的构造函数中将其初始化为_dispatcher=newdispatcherimpl(这个)。当我编写player.getDispatcher()->dispatchEvent(eventID,event)时,我(在Visual Studio中)遇到以下错误:无法将“std::basic\u string”转换为“void(\uu thiscall player::*)(int)”
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);
}
}
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