I'm trying to write code which can find the distance between lots of different types of shapes. I've defined a base class Shape
with a virtual distance(Shape& otherShape)
function to find the distance to another shape and then want to define that for all my derived classes.
The problem is that there are lots of possible pairs of shapes, so my solution was to define a set of distance functions outside the classes (circle-circle, circle-square, square-tri etc.) and then call the corresponding one from the distance function. I've added a mini example of what I mean below, with just one derived class Circle
to demonstrate the problem.
When I try and call my specific circleCircleDistance
function I get an error because it can't convert the base class into the derived class. Is there any way I can address this or will my design as it stands just not work?
enum ShapeType{CIRCLE, SQUARE};
class Shape {
public:
ShapeType type;
virtual double distance(Shape& otherShape) = 0;
};
class Circle : public Shape {
public:
ShapeType type = CIRCLE;
double distance(Shape& otherShape) override;
};
double circleCircleDistance(Circle& circle1, Circle& cirlce2){
return 0; //pretend this does the calculation
};
double Circle::distance(Shape &otherShape) {
switch (otherShape.type){
case CIRCLE:
//Here I get the error
//cannot bind base class object of type Shape to derived class reference Circle& for 2nd argument
return circleCircleDistance(*this, otherShape);
}
}
You would have to cast the Shape&
to a Circle&
return circleCircleDistance(*this, static_cast<Circle&>(otherShape));
As an aside, I'd handle your types a bit differently
class Shape {
public:
virtual ShapeType get_type() const = 0; // derived classes must override this
virtual double distance(Shape& otherShape) = 0;
};
class Circle : public Shape {
public:
ShapeType get_type() const override { return CIRCLE; } // here's your override
double distance(Shape& otherShape) override;
};
...
{
switch (otherShape.get_type()){
Otherwise you're going to get into a situation where type
is shadowed from the derived/base classes depending how you access it.