简体   繁体   English

C ++中的调度表

[英]Dispatch Table in C++

Suppose I have something like the following: 假设我有以下内容:

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;
}

I am wondering what the best way to define a dispatch table for a function like 我想知道为函数定义调度表的最佳方法是什么

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

The classes are written in C++, but the distanceTo function and the struct must be externed to C 这些类是用C ++编写的,但distanceTo函数和struct必须被激活到C语言

thanks 谢谢

I would make the class diagram different: an abstract base class GeomObject , subclassing geometry (with a getType accessor, as well as pure virtual distanceTo overloads), and concrete subclasses Line and Point of GeomObject (with overrides of the accessor and overloads). 我会使类图不同:一个抽象基类GeomObject ,子类化geometry (使用getType访问器,以及纯虚拟distanceTo重载),以及具体的子类LinePoint of GeomObject (具有访问器和重载的覆盖)。 The need to "extern C" the double distanceTo function is not a problem, since you're not talking about overloads of that function anyway: you simply want to return geom1.distanceTo(x) (letting the virtual table do that part of the work;-) where x is an appropriate cast, eg, assuming the class diagram I've explained: 需要"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));
  }
}

I would use double dispatch with Visitor pattern . 我会使用访问者模式的双重调度 Then you only have to have two pointers to geometry objects and let double dispatch call the appropriate virtual distanceTo function based on actual dynamic types of two objects, which you can do from your C function. 然后,您只需要有两个指向geometry对象的指针,并让double dispatch根据两个对象的实际动态类型调用相应的虚拟distanceTo函数,您可以从C函数执行此操作。

(updated to match updated question) (已更新以匹配更新的问题)

To avoid duplication move your conversion code in one helper function and let C++ do the rest of the work: 为避免重复,请将转换代码移到一个辅助函数中,让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));

could you do something simple like: 你可以做一些简单的事情:

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

you can implement this part in C++ and expose the function through the extern "C" 你可以用C ++实现这个部分,并通过extern“C”公开函数

then you could perhaps provide a method in your geometrical classes to accept geometrical struct as a parameter and perform dispatching inside the classes using regular C++ function overload. 那么您可以在几何类中提供一个方法来接受几何结构作为参数,并使用常规C ++函数重载在类内执行调度。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM