Domanda

Supponiamo che io ho qualcosa di simile al seguente:

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

Mi chiedo che cosa il modo migliore per definire una tabella di invio per una funzione come

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

Le classi sono scritte in C ++, ma la funzione distanceTo e struct devono essere externed a C

grazie

È stato utile?

Soluzione

Vorrei fare il diagramma di classe diversa: una classe di base astratta GeomObject, sottoclasse geometry (con una funzione di accesso getType, così come pure i sovraccarichi distanceTo virtuali), e sottoclassi concrete Line e Point di GeomObject (con override del la funzione di accesso e sovraccarichi ). La necessità di "extern C" la funzione double distanceTo non è un problema, dal momento che non stiamo parlando di sovraccarichi di quella funzione in ogni caso: si vuole semplicemente tornare geom1.distanceTo(x) (lasciando la tabella virtuale fare quella parte del lavoro; -) dove x è un cast adeguato, ad esempio, supponendo che il diagramma delle classi ho spiegato:

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

Altri suggerimenti

doppia spedizione con visitatore modello . Allora dovete solo avere due puntatori a geometry oggetti e lasciare doppia spedizione chiamare la funzione distanceTo virtuale appropriata in base ai tipi dinamici effettivi di due oggetti, che si può fare da vostra funzione C.

(aggiornato per abbinare domanda aggiornato)

Per evitare la duplicazione spostare il codice di conversione in una funzione di supporto e sia C ++ fare il resto del lavoro:

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

si potrebbe fare qualcosa di semplice come:

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

è possibile implementare questa parte in C ++ ed esporre la funzione tramite l'extern "C"

allora si potrebbe forse fornire un metodo nelle classi geometriche di accettare struct geometrica come parametro ed eseguire dispacciamento all'interno delle classi che utilizzano regolarmente il sovraccarico funzione C ++.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top