减少重复的方法?

时间:2012-12-24 18:32:18

标签: c++ oop class friend

所以我正在研究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,然后代替distanceorbitV。所以我最终为每次计算都有四个函数。正如您从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这是它应该输出的内容以及它现在如何工作

3 个答案:

答案 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 {


 };

这样可以轻松扩展到需要相同原理的未来对象。

在对象类中,您将拥有一些基本属性:

  • 物理(可选)
  • 尺寸
  • 速度(最后计算的速度)
  • 控制(bool - 当前控制船舶与否)

这样就无需与calcship类保持紧密关系。

接下来,您将更改calc课程以使其成为一般课程。您不希望依赖单个船舶对象,这很麻烦。

选项1

您可以为每个对象创建calc类的实例。此calc实例可以访问objectship类的已有属性。

选项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成为单身人士,使其成为命名空间 我现在就去做。