3

Given following classes:

class Geometry {
  public:
    double distanceBetweenGeometries(const Geometry& g);
  private:        
    Shape myShape;
};

class Shape {
  public:
    double distance(const Shape& s1, const Shape& s2);
};

class Rectangle : public Shape {
  private:
    double i,j,length,width;
};

class Circle : public Shape {
  private:
    double i,j,radius;
};

So each geometry got a shape of type Rectangle or Circle. In my program I need to calculate the (Euclidean) distance between two geometries. Thus, given two geometries g1 and g2 I call

g1.distanceBetweenGeometries(g2);

and I want to return the distance between g1.myShape and g2.myShape.

I already know how to calculate the distance between two rectangles, two circles or between a rectangle and a circle. Somehow, I did not achieve an object-orientated solution for implementing the distance-function.

My idea is: Call the distance-function from a given geometry. This distance function calls the distance-function of a shape. In Shape::distance(..) I somehow need to differentiate of which type s1 and s2 are. Afterwards, I have to choose the correct mathematical formula to compute the distance between them. Can you tell me if my inheritance-idea is adequate here and how to implement the Shape::distance(..) function so that it can automatically determine which formula is requested for distance-computation?

Kapa11
  • 311
  • 2
  • 18
  • c++ doesn't have native *multiple dispatch*, you have to implementing your own. – Jarod42 Dec 09 '16 at 13:26
  • If you store a `Shape`, you lose all the extra information provided by `Rectangle` or `Circle`, so you won't be able to access information such as `length` or `width`, and thus you will probably not be able to compute the distance you want. – Holt Dec 09 '16 at 13:33
  • So could you tell me what `Geometry` should save instead of a `Shape`? – Kapa11 Dec 09 '16 at 13:39
  • Take a look at the visitor pattern, it is useful to implement double dispatch, which is what it seems you need. – Xaqq Dec 09 '16 at 13:42
  • Possible dublication of an other [question](http://stackoverflow.com/questions/1749534/multiple-dispatch-in-c). Generally the question is about _multiple dispatch_ as was mentioned above, it should be a start point. – Trollliar Dec 09 '16 at 14:02

1 Answers1

2

You may do something like:

class Circle;
class Rectangle;

// Your existing methods to do the real computation:
double distanceRC(const Rectangle&, const Circle&);
double distanceRR(const Rectangle&, const Rectangle&);
double distanceCC(const Circle&, const Circle&);

class Shape {
public:
    virtual ~Shape() = default;
    virtual double distanceWith(const Shape&) const = 0;
    virtual double distanceWith(const Rectangle&) const = 0;
    virtual double distanceWith(const Circle&) const = 0;
};

class Rectangle : public Shape {
public:
    double distanceWith(const Shape& s) const override { return s.distanceWith(*this); }
    double distanceWith(const Rectangle& r) const override { return distanceRR(*this, r);}
    double distanceWith(const Circle& c) const override { return distanceRC(*this, c); }
private:
    double i,j,length,width;
};

class Circle : public Shape {
public:
    double distanceWith(const Shape& s) const override { return s.distanceWith(*this); }
    double distanceWith(const Rectangle& r) const override { return distanceRC(r, *this);}
    double distanceWith(const Circle& c) const override { return distanceCC(*this, c); }
private:
    double i,j,radius;
};
Jarod42
  • 203,559
  • 14
  • 181
  • 302
  • I got no admin privileges and I can only compile using `-std=c++0x` and not `-std=c++11` (using GCC 4.4.7, I may not update it :( ). Your code will also work if I leave the `override`-statement, doesn't it? Right now, I get the error `..: error: expected ';' before 'override'`. `Override` will not have a huge impact here or am I wrong? – Kapa11 Dec 09 '16 at 13:54
  • You may remove `override` if you cannot compile in c++11. – Jarod42 Dec 09 '16 at 13:56
  • Ok, thanks for your efforts :) It's exactly what I needed to do. – Kapa11 Dec 09 '16 at 13:58
  • that's a lot of repetition. Shouldn't distance be computed between `center`s? Couldn't finding the centre be polymorphic? – Richard Hodges Dec 09 '16 at 14:05
  • I need to compute the minimal distance between two `Shape`s. It's easy for me to compute the distance between their centers but finding the minimal distance between two outer lines is not as easy and needs more computation effort. That's why I choose to implement each distance in a separate function. – Kapa11 Dec 09 '16 at 14:10