C++ C++;使用互不相关的对象调用双重分派方法
我有一系列形状对象,可以检查它们是否相互相交(如果任一对象的任何部分重叠,则相交为真)。这对于双重分派非常有效,因为两个对象的交集可以相对于任何一个对象表示,并且仍然有效且真实 我最近添加了(读作:“尝试添加”)一个Contains方法,用于测试一个形状是否完全包围另一个形状。双重分派失败,因为两个大小不同的形状将用于相交,但不包含:C++ C++;使用互不相关的对象调用双重分派方法,c++,double-dispatch,C++,Double Dispatch,我有一系列形状对象,可以检查它们是否相互相交(如果任一对象的任何部分重叠,则相交为真)。这对于双重分派非常有效,因为两个对象的交集可以相对于任何一个对象表示,并且仍然有效且真实 我最近添加了(读作:“尝试添加”)一个Contains方法,用于测试一个形状是否完全包围另一个形状。双重分派失败,因为两个大小不同的形状将用于相交,但不包含:shape\u one是一个大圆,shape\u two是一个完全由shape\u one包围的较小圆。调用shape\u one.Contains(shape\u
shape\u one
是一个大圆,shape\u two
是一个完全由shape\u one
包围的较小圆。调用shape\u one.Contains(shape\u two)
将返回true,但shape\u two.Contains(shape\u one)
将返回false
有没有一种方法可以对这种类型的场景实施双重调度?
(鼓励编辑标题以增加对问题的理解…)
具有双重分派的相交方法示例:
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;
}
//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());
}
通过将contains方法推送到基类,并在base-to-base-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
bool Shape::Contains(const Shape&Shape)const{
std::string type=shape.GetShapeType();
如果(类型=“弧”){
返回此->包含(动态施法(形状));
}else if(类型=“圆圈”){
返回此->包含(动态施法(形状));
}else if(类型==“椭圆”){
返回此->包含(动态施法(形状));
}else if(类型=“行”){
返回此->包含(动态施法(形状));
}否则如果(类型=“点”){
返回此->包含(动态施法(形状));
}else if(类型==“多边形”){
返回此->包含(动态施法(形状));
}else if(类型==“矩形”){
返回此->包含(动态施法(形状));
}else if(类型==“扇区”){
返回此->包含(动态施法(形状));
}else if(类型==“样条曲线”){
返回此->包含(动态施法(形状));
}else if(类型=“三角形”){
返回此->包含(动态施法(形状));
}否则{
返回false;
}
}
布尔形状::包含(常数点和点)常数{
返回此->相交(点);
}
布尔形状::包含(常量行和行)常量{
返回this->Intersects(line.GetPointOne())和&this->Intersects(line.GetPointTwo());
}
布尔形状::包含(常量矩形和矩形)常量{
返回this->Intersects(rectangle.gettoplft())&this->Intersects(rectangle.GetTopRight())&this->Intersects(rectangle.GetBottomLeft())&this->Intersects(rectangle.GetBottomRight());
}
//…等等