У меня есть три класса формы Circle
, Square
, ConvexPolygon
и у меня есть функции
bool ShapesIntersect(const Circle& s1, const Circle& s2);
bool ShapesIntersect(const Circle& s1, const Square& s2);
// ... and the other 7 combinations
Я хотел бы полиморфную функцию вроде как
Matrix<bool> ComputeShapeIntersectionMatrix(
const vector<Shape>& shapes1,
const vector<Shape>& shapes2);
это вызывает специфичные для формы методы выше, чтобы заполнить матрицу пересечений.
Я думаю, что это невозможно сделать точно в C ++, но я в порядке с любым другим решением, если я могу добавить новый тип фигуры без изменения кода, который вычисляет матрицу пересечений.
Я сделал мульти-диспетчерская.
Если вы используете std::variant
, становится проще:
using Shape = std::variant<Circle, Square, ConvexPolygon>;
struct intersect
{
template <typename Shape1, typename Shape2>
bool operator()(const Shape1& lhs, const Shape2& rhs) const {
return ShapesIntersect(lhs, rhs);
}
};Matrix<bool> ComputeShapeIntersectionMatrix(
const vector<Shape>& shapes1,
const vector<Shape>& shapes2)
{
Matrix<bool> res(shapes1.size(), shapes2.size());
for (std::size_t i = 0; i != shapes1.size(); ++i) {
for (std::size_t j = 0; j != shapes2.size(); ++j) {
res[i][j] = std::visit(intersect{}, shapes1[i], shapes2[j]);
}
}
return res;
}
Я бы решил это так:
struct Circle;
struct Polygon;
struct Square;
struct Intersector {
virtual bool intersects(const Circle& ) const = 0;
virtual bool intersects(const Polygon& ) const = 0;
virtual bool intersects(const Square& ) const = 0;
};
template<class SHAPE>
struct ShapeIntersetor;
template<>
struct ShapeIntersetor<Square> : Intersector {
const Square& square;
ShapeIntersetor(const Square& square) : square(square) { }
bool intersects(const Circle& ) const override { /* Intersection code */ }
bool intersects(const Polygon& ) const override { /* Intersection code */ }
bool intersects(const Square& ) const override { /* Intersection code */ }
};
// Repeat above for each shape type
struct Shape {
virtual ~Shape() = default;
virtual std::unique_ptr<Intersector> get_intersector() const = 0;
virtual bool intersects(const Intersector& isector) const = 0;
};
struct Polygon : Shape {
std::unique_ptr<Intersector> get_intersector() const override {
return make_unique<ShapeIntersector<Polygon>>(*this);
}
bool intersects(const Intersector& isector) const override {
return isector.intersects(*this);
}
};
// Repeat above for each shape type