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++代码中抛出指针/指针),那就没问题了。