我正在创造一个游戏,在这个游戏中,球可以以各种方式被捕获,这些都会导致不同的行为。最初,我想在接球时为某个通用方法添加一个枚举,然后将球委托以某种方式抓住球时发生的动作。一个例子是:
void Weapon::Catch(Character Catcher, CatchMethod Method)
{
switch (Method)
{
case Method::PickUp: OnPickup(Catcher); break;
case Method::Pass: OnPass(Catcher); break;
// etc
}
}
这将允许我将该函数称为:
MyWeapon->Catch(Catcher, Method::Pickup);
MyWeapon->Catch(Catcher, Method::Pass);
等。我认为这会比
更好看MyWeapon->CatchByPickup(Catcher);
MyWeapon->CatchByPass(Catcher);
然而,我的主要问题是,这根本不可扩展,这是我实际上希望用这种通用方法实现的。如果我将方法设为枚举,我不能简单地扩展枚举并覆盖Catch
的派生类中的虚拟Weapon
方法。如果我决定在某个派生类中扩展该方法,我必须创建一个新的枚举,它从Method
枚举的最后一个值开始。我不认为这是处理这种情况的正确方法,但我不知道这种情况下的最佳做法是什么。它可能涉及模板专业化吗?对我来说,主要的问题是我不能简单地扩展枚举。
答案 0 :(得分:3)
您可以使用std::function
。
using CatchMethod = std::function<void(Character)>;
void Weapon::Catch(Character Catcher, CatchMethod Method)
{
Method(Catcher);
}
调用该函数非常简单
// If its a regular function you can just use the pointer to the function
weapon.Catch(Player, &OnPickup);
// If its a member function you can use lambda
weapon.Catch(Player, [this](Character Catcher){OnPickup(Catcher);});
// or std::bind (slightly more verbose and less flexible)
weapon.Catch(Player, std::bind(&Weapon::OnPickup, this, std::placeholders::_1));
答案 1 :(得分:1)
这有点不明显,因为我不确定你的Catch
方法中是否有与系统相关的任何其他代码,但是听起来你不想使用方法完全反转控件以具有不同的功能。像这样,例如:
void pickup(Weapon weapon, Character catcher) {
/* Do whatever your OnPickup does */
}
void pass(Weapon weapon, Character catcher) {
/* Do whatever your OnPass does */
}
然后,显然,只需要这样称呼它们:
pickup(MyWeapon, Catcher);
pass(MyWeapon, Catcher);
如果没有您在问题中没有显示的周围代码或类似的先决条件,我认为没有任何背面,并且声明执行类似操作的新功能完全是分散的和可扩展的。< / p>
如果你需要通过其他函数传递CatchMethod
,你可以简单地传递一个函数指针。
顺便说一句,顺便说一句,除非Weapon
和Character
这里有typedef到其他东西,否则按值传递这些东西通常是个坏主意。您可能想要使用引用或指针。