3

假设我有以下内容:

class Point : geometry {
   ...
   Point(double x, double y) {
   }
   double distanceTo(Line) {
   }
   double distanceTo(Point) {
   }
}
class Line : geometry {
   ...
   Line(double x, double y, double slopex, double slopey) {
   }
   double distanceTo(Line) {
   }
   double distanceTo(Point) {
   }
}
struct point_t {
    double x, y;
}
struct line_t {
    double x, y, slope_x, slope_y;
}
struct Geom_Object_t {
   int type;
   union {
       point_t p;
       line_t l;
   } geom;
}

我想知道为类似的函数定义调度表的最佳方法是什么

double distanceTo(Geom_Object_t * geom1, Geom_Object_t * geom2) {
}

这些类是用 C++ 编写的,但是 distanceTo 函数和结构必须外部到 C

谢谢

4

4 回答 4

3

我会让类图有所不同:抽象基类GeomObject、子类化geometry(带有getType访问器以及纯虚拟distanceTo重载)和具体子类LinePointof GeomObject(带有访问器和重载的覆盖)。"extern C"对函数的需求double distanceTo不是问题,因为无论如何您都不是在谈论该函数的重载:您只是想返回geom1.distanceTo(x)(让虚拟表完成那部分工作;-)x适当的演员表在哪里,例如,假设我已经解释了类图:

extern "C"
double distanceTo(Geom_Object_t * geom1, Geom_Object_t * geom2) {
  if(geom2->getType() == POINT_TYPE) {
    return geom1->distanceTo(static_cast<Point*>(geom2));
  } else {
    return geom1->distanceTo(static_cast<Line*>(geom2));
  }
}
于 2010-01-16T05:07:42.687 回答
2

我会使用双重调度和访客模式。然后你只需要有两个指向geometry对象的指针,并让双重调度根据两个对象的实际动态类型调用适当的虚distanceTo函数,你可以从你的 C 函数中做到这一点。

于 2010-01-16T05:09:44.583 回答
1

(更新以匹配更新的问题)

为避免重复,将转换代码移到一个辅助函数中,让 C++ 完成其余工作:

geometry makeg(Geom_Object_t* g) {
    switch(g->type) {
         case TYPE_POINT: return Point(g->geom.p.x, g->geom.p.y);
         case TYPE_LINE : return Line(g->geom.l.x, g->geom.l.y, g->geom.l.slope_x, g->geom.l.slope_y);
         // ...
    }
}

makeg(geom1).distanceTo(makeg(geom2));
于 2010-01-16T05:18:30.993 回答
0

你能做一些简单的事情吗:

if (g1->type == LINE) {
  if (g2->type == LINE) 返回 g1->distance(g2->l);
  如果 (g2->type == POINT) ...
}
别的 ...

您可以在 C++ 中实现这部分并通过 extern "C" 公开该功能

那么您也许可以在几何类中提供一个方法来接受几何结构作为参数,并使用常规 C++ 函数重载在类内部执行调度。

于 2010-01-16T05:10:10.467 回答