代码之家  ›  专栏  ›  技术社区  ›  adk

C++中的调度表

  •  3
  • adk  · 技术社区  · 15 年前

    假设我有如下内容:

    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++编写的,但是函数的间距和结构必须被转换成C。

    谢谢

    4 回复  |  直到 15 年前
        1
  •  3
  •   Alex Martelli    15 年前

    我将使类图不同:抽象基类 GeomObject 子类 geometry (用) getType 访问器,以及纯虚拟 distanceTo 重载)和具体的子类 Line Point 属于 地物 (使用访问器和重载的重写)。需要 "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));
      }
    }
    
        2
  •  2
  •   Alex B    15 年前

    我会用 double dispatch with Visitor pattern . 那么你只需要有两个指向 geometry 对象并让双调度调用适当的虚拟 distanceTo 基于两个对象的实际动态类型的函数,您可以从C函数中执行此操作。

        3
  •  1
  •   Georg Fritzsche    15 年前

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

    为了避免重复,在一个助手函数中移动转换代码,并让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));
    
        4
  •  0
  •   Anycorn    15 年前

    你能做些简单的事吗?

    if (g1->type == LINE) {
      if (g2->type == LINE) return g1->distance(g2->l);
      if (g2->type == POINT) ...
    }
    else ...
    

    您可以在C++中实现这一部分,并通过外部“C”来公开该函数。

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

    推荐文章