如何专业地重构lambda函数以便被另一个类调用WHILE使得调用者的代码仍然很短?
我的尝试表明,为了将lambda函数更改为普通函数,我必须手动捕获变量,因此新的普通函数需要更多参数(以补偿自动捕获能力)。
因此,新功能使用起来更加繁琐,并且可能导致更多错误。
这是我的原始代码,使用lambda。
void Turret::registerFullversion(int gameObjectId, PhysicObject* phyO){//utility
//.... something a bit complex .......
}
void Turret::createTurret(int typeOfTurret){
int gameObjectId=createNewGameObjectId();
auto registerEasy=[&]( PhysicObject* phyO){
//^ served as a short hand version of "registerFullversion"
// 1 parameter is more comfortable than 2
registerFullversion(gameObjectId,phyO);
}
switch(typeOfTurret){
case 1:{ //this part will be moved into another class (###)
PhysicObject* phy=PhysicSystem::createNewPhysicObject();
registerEasy( phy);
//^ equivalent to "registerFullversion(gameObjectId,phy)"
// but it is very concise (1 parameter), nice!
};break;
//..... a lot of case ....
}
//... do something about "gameObjectId"
}
我想将函数的一部分(###)从Turret
移动到另一个类(TurretLaser
)。
它有效,但结果是调用者必须捕获gameObjectId
并手动传递它: -
void Turret::createTurret(int typeOfTurret){
int gameObjectId=createNewGameObjectId();
switch(typeOfTurret){
case 1:{ //this part have to be move into another class
TurretLaser::createTurret(gameObjectId)
};break;
//..... a lot of case ....
}
}
void TurretLaser::createTurret(int gameObjectId){ //(###)
PhysicObject* phy=PhysicSystem::createNewPhysicObject();
Turret:registerFullversion(gameObjectId,phy);
//^ it is not as short as before (now = 2 parameters)
}
std::bind
和std::function
是不允许的。我将手动捕获相关数据(gameObjectId
)并对其进行缓存(使用新变量CACHE_gameObjectId
): -
void Turret::registerEasy(PhysicObject* physicO){
registerFullversion(CACHE_gameObjectId,physicO);
//int "CACHE_gameObjectId" is a new field of "Turret"
};
void Turret::createTurret(int typeOfTurret){
int gameObjectId=createNewGameObjectId();
Turret::CACHE_gameObjectId=gameObjectId;
switch(typeOfTurret){
case 1:{ //this part have to be move into another class
TurretLaser::createTurret(gameObjectId)
};break;
//..... a lot of case ....
}
}
void TurretLaser::createTurret(int gameObjectId){ //(###)
PhysicObject* phy=PhysicSystem::createNewPhysicObject();
Turret:registerEasy(phy);
//^ short as before, nice
}
我的解决方案的缺点:脏,看起来很危险(不是那么自动,因此会导致更多的bug),似乎不那么线程安全(?)