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オーバーロードを使用)、および具体的なサブクラスLinePointオブGeomObject(アクセサーとオーバーロードのオーバーライドを使用)。とにかくその関数のオーバーロードについて話しているわけではないので"extern C"、関数の必要性は問題ではありません:単に戻りたい(仮想テーブルにその部分の作業をさせます;-)適切なキャストはどこですか?たとえば、私が説明したクラス図を仮定すると:double distanceTogeom1.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

訪問者パターンで二重ディスパッチを使用します。次に、オブジェクトへの 2 つのポインターを用意するだけでよく、2 つのオブジェクトの実際の動的な型に基づいてgeometry、ダブル ディスパッチで適切な仮想関数を呼び出せます。これは、C 関数から実行できます。distanceTo

于 2010-01-16T05:09:44.583 に答える
1

(更新された質問に合わせて更新)

重複を避けるために、変換コードを 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) return g1->distance(g2->l);
  if (g2->type == POINT) ...
}
そうしないと ...

この部分を C++ で実装し、extern "C" を介して関数を公開できます。

次に、幾何学的クラスにメソッドを提供して、幾何学的構造体をパラメーターとして受け入れ、通常の C++ 関数のオーバーロードを使用してクラス内でディスパッチを実行することができます。

于 2010-01-16T05:10:10.467 に答える