所以我正在研究2D空间模拟器,我有资源管理器'calc
'来处理所有事情的所有计算。例如,来自calc.hpp
:
var calc::eccentricity (object A, object B);
var calc::distance (object A, object B);
var calc::orbitV (object A, object B);
等。但是,我的程序结构的方式是我的calc
课程
private:
object *ship //the currently controlled ship
object *targ //target
object *ref //reference (from which speeds, position, etc. are calculated)
并且使用第一个例子中给出的计算,我为每个计算函数写了三个函数,如下所示:
var calc::ship_ecc (object A){
if(!ship) //catches null pointers
return NAN;
return eccentricity(*ship, A);
}
var calc::ship_ref_ecc (){
if(!ref) //catches null pointers
return NAN;
return ship_ecc(*ref);
}
var calc::ship_targ_ecc (){
if(!targ) //catches null pointers
return NAN;
return ship_ecc(*targ);
}
代表eccentricity
,然后代替distance
和orbitV
。所以我最终为每次计算都有四个函数。正如您从calc.hpp
所看到的,这会产生大量重复的代码。重复的代码是坏事。
有没有办法打电话
calc.ship.targ.eccentricity();
calc.ship.ref.eccentricity(); //or variation thereof
或
calc.ship.targ(eccentricity);
calc.ship.ref(eccentricity); //or variation thereof
而不是
calc.ship_targ_ecc();
calc.ship_ref_ecc();
?我想知道你是否可以做一些花哨的operator()
重载,或传递一个函数,或者在friend
中创建一个calc
类。理想情况下,我应该只能访问行public
,{{1}}。
谢谢!
编辑:为yall做了一个例子:31 - 53
这是它应该输出的内容以及它现在如何工作
答案 0 :(得分:1)
这可能会改变您当前的代码。但我认为calc中的函数应该是object的成员。所以你可以这样:
ship.eccentricity(target);
让我感到困惑的是(这里可能是最大的问题)是你似乎在你的calc对象(私有成员)中定义了一些硬关系。这些是为了什么?从代码中,我猜每个“船”都有一个计算对象。如果是,那么将代码添加到object而不是维护object和calc之间的1-1关系是另一个原因。
答案 1 :(得分:1)
这可能需要一点点重构,但我认为这是值得的。对于简单的游戏,您可以使用OOP和多态来解决问题。
首先,创建一个object
类。
class Object {
public:
Object();
~Object();
};
此对象类将成为游戏中所有对象(船舶,角色等)的基础。然后,您将为ship
创建一个子类。
class Ship : public Object {
};
这样可以轻松扩展到需要相同原理的未来对象。
在对象类中,您将拥有一些基本属性:
这样就无需与calc
和ship
类保持紧密关系。
接下来,您将更改calc
课程以使其成为一般课程。您不希望依赖单个船舶对象,这很麻烦。
选项1
您可以为每个对象创建calc
类的实例。此calc
实例可以访问object
和ship
类的已有属性。
选项2
创建一个通用calc
类,要求您传递对船舶/对象实例的引用。 calc->eccentricity(&ship, target);
选项3
在可能的manager
类或简单的“全局”变量中。您可以保留对当前受控船舶的引用(如果这是您的系统的工作方式,我不确定)。或者您可以存储船舶的索引,所有实例都保存在vector<&Ship>
。
在一个简单的游戏中,直接的OOP就足够了,但如果你想要更多的去耦,基于组件的游戏设计将是一个更好的选择(当然与OOP结合)。
答案 2 :(得分:0)
所以我把它带到/r/learnprogramming,我从zzyzzyxx得到了一个很好的答案(一如既往)。他的回答是:
简单地使用需要两个或三个参数的函数有什么问题?它们不必属于任何特殊的
calc
类。也许是一个calc
命名空间。我不确定你的设计的其余部分是否有意义,但是如何使它成为一个成员函数,以便任何东西都可以计算出给定目标需要什么,如果没有合理的默认值,可能会有参考点?
基本上,不要担心所有这些calc.eccentricity(A, B)
,calc.ship_ecc(A)
,calc.ship_ref_ecc()
业务,只需说
calc.eccentricity(*calc.targ(), B)
另外,不要让calc
成为单身人士,使其成为命名空间
我现在就去做。