Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/128.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/65.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ C+中的调度表+;_C++_C_Dispatch Table - Fatal编程技术网

C++ C+中的调度表+;

C++ C+中的调度表+;,c++,c,dispatch-table,C++,C,Dispatch Table,假设我有如下内容: 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) { } do

假设我有如下内容:

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


谢谢

我会让类图与众不同:抽象基类
地貌对象
,子类化
几何体
(使用
getType
访问器,以及纯虚拟的
距离
重载),以及
地貌对象的具体子类
(使用访问器重写和重载)。需要
“extern C”
双距离to
函数不是一个问题,因为您并不是在谈论该函数的重载:您只需要返回
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));
  }
}
extern“C”
双距离(几何对象几何1,几何对象几何2){
if(geom2->getType()==点类型){
返回geom1->distanceTo(静态施法(geom2));
}否则{
返回geom1->distanceTo(静态施法(geom2));
}
}

我会使用。然后,您只需要有两个指向
几何体的指针,让double dispatch根据两个对象的实际动态类型调用相应的虚拟
距离to
函数,这可以通过C函数实现。

您能做一些简单的事情吗,如:

if (g1->type == LINE) { if (g2->type == LINE) return g1->distance(g2->l); if (g2->type == POINT) ... } else ... 如果(g1->类型==行){ 如果(g2->type==LINE)返回g1->distance(g2->l); 如果(g2->类型==点)。。。 } 其他的

可以在C++中实现这个部分,并通过外部的“C”< /P>公开该函数

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

(更新到匹配更新问题)

避免重复,将转换代码移到一个辅助函数中,并让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));

但是,该结构不能再从C中使用。@adk,不是,但是你说只有
distanceTo
函数需要是
“extern C”
!@adk,是的,有了你的“澄清”,很明显你原来的解决方案也打破了你的限制——要“extern C”一个结构,它必须是一个“普通的旧数据”一个,因此特别是与一个或多个具有重载方法的类没有联合…将其外部化到C不是标准的/可移植的。因此,重新考虑您的约束或通过指针添加一个间接级别(这将使我的答案完全
“extern C”
当然也可以;-).@Alex Martelli对此表示抱歉。@adk,现在您只需要根据需要为每个操作数构建一个
线
(取决于
类型
),这样做时我的答案仍然适用(只需调用抽象基类
Foobar
,因为您完全重新定义了参数“指向类,
Geom\u object\u t
”的含义——您真的需要我解释一下吗?-)如果你有10种不同的类型和20种方法each@adk不,但是通过让C++选择正确的重写,如在我的答案中,它是一个代码< O(m)< /C> >代码大小的问题(最好如果<代码> m),没有一种可移植的方式来“Autoto C”ActhEng>结构> <代码>,其中包含了不为原始数据的类< <代码>联合<代码>。(如果它们有方法重载),点和线不是,如果你想要一个不可移植的解决方案,针对某个特定的专有C++编译器,请提及;否则,重新考虑你不完善的约束,因为你要问的(如果要求是符合标准的和可移植的)这是不可行的,所以你可能要用C++来实现,比如一个带有指针的结构(并且在C++代码中抛出指针/指针),那就没问题了。