C ++ Вызов метода двойной отправки с объектами, которые не относятся друг к другу

У меня есть ряд объектов формы, которые могут проверить, пересекаются ли они друг с другом (пересечение истинно, если какая-либо часть одного объекта перекрывает другую). Это прекрасно работает с двойной диспетчеризацией, потому что пересечение двух объектов может быть представлено относительно любого объекта и при этом быть действительным и истинным.

Недавно я добавил (читается как: «попытался добавить») метод Contains, который проверяет, полностью ли форма охватывает другую. Двойная отправка не удалась, потому что две формы разных размеров будут работать на Intersect, но не содержит: shape_one большой круг, и shape_two меньший круг, полностью окруженный shape_one, Вызов shape_one.Contains(shape_two) вернется правда, но shape_two.Contains(shape_one) вернет ложь.

Есть ли способ реализовать двойную диспетчеризацию для этого типа сценария?

(Редактирование заголовков рекомендуется для лучшего понимания вопроса …)

Пример методов Intersects с двойной отправкой:

bool Rectangle::Intersects(const Shape& shape) const {
return shape.Intersects(*this);
}

bool Rectangle::Intersects(const Point& point) const {
return point.Intersects(*this);
}

bool Rectangle::Intersects(const Line& line) const {
return line.Intersects(*this);
}

bool Rectangle::Intersects(const Rectangle& rectangle) const {
double myTop = this->GetY();
double myLeft = this->GetX();
double myRight = myLeft + this->GetWidth();
double myBottom = myTop + this->GetHeight();
double rTop = rectangle.GetY();
double rLeft = rectangle.GetX();
double rRight = rLeft + rectangle.GetWidth();
double rBottom = rTop + rectangle.GetHeight();

if(myTop > rBottom) return false;
if(myBottom < rTop) return false;
if(myLeft > rRight) return false;
if(myRight < rLeft) return false;

return true;
}

Пример методов Contains с двойной отправкой:

//THIS RESULTS IN A STACK OVERFLOW! DUE TO INFINITE RECURSION!
bool Rectangle::Contains(const Shape& shape) const {
return this->Contains(shape);
}

//THIS IS NOT TRUE IN ALL CASES!
bool Rectangle::Contains(const Shape& shape) const {
return shape.Contains(*this);
}bool Rectangle::Contains(const Point& point) const {
return this->Intersects(point);
}

bool Rectangle::Contains(const Line& line) const {
return this->Intersects(line.GetPointOne()) && this->Intersects(line.GetPointTwo());
}

bool Rectangle::Contains(const Rectangle& rectangle) const {
return this->Intersects(rectangle.GetTopLeft()) && this->Intersects(rectangle.GetTopRight()) && this->Intersects(rectangle.GetBottomLeft()) && this->Intersects(rectangle.GetBottomRight());
}

0

Решение

Решается путем нажатия, содержит методы до базового класса и динамическое приведение к нужному типу с параметром типа в вызове от базы к базе Contains:

bool Shape::Contains(const Shape& shape) const {
std::string type = shape.GetShapeType();
if(type == "arc") {
return this->Contains(dynamic_cast<const Arc&>(shape));
} else if(type == "circle") {
return this->Contains(dynamic_cast<const Circle&>(shape));
} else if(type == "ellipse") {
return this->Contains(dynamic_cast<const Ellipse&>(shape));
} else if(type == "line") {
return this->Contains(dynamic_cast<const Line&>(shape));
} else if(type == "point") {
return this->Contains(dynamic_cast<const Point&>(shape));
} else if(type == "polygon") {
return this->Contains(dynamic_cast<const Polygon&>(shape));
} else if(type == "rectangle") {
return this->Contains(dynamic_cast<const Rectangle&>(shape));
} else if(type == "sector") {
return this->Contains(dynamic_cast<const Sector&>(shape));
} else if(type == "spline") {
return this->Contains(dynamic_cast<const Spline&>(shape));
} else if(type == "triangle") {
return this->Contains(dynamic_cast<const Triangle&>(shape));
} else {
return false;
}
}

bool Shape::Contains(const Point& point) const {
return this->Intersects(point);
}

bool Shape::Contains(const Line& line) const {
return this->Intersects(line.GetPointOne()) && this->Intersects(line.GetPointTwo());
}

bool Shape::Contains(const Rectangle& rectangle) const {
return this->Intersects(rectangle.GetTopLeft()) && this->Intersects(rectangle.GetTopRight()) && this->Intersects(rectangle.GetBottomLeft()) && this->Intersects(rectangle.GetBottomRight());
}

//...etc
0

Другие решения

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector