0

互いに交差しているかどうかを確認できる一連の形状オブジェクトがあります (いずれかのオブジェクトの一部が他のオブジェクトと重なっている場合、交差は true です)。これは、2 つのオブジェクトの交差をいずれかのオブジェクトに対して相対的に表すことができ、依然として有効かつ真であるため、二重ディスパッチでうまく機能します。

最近、図形が別の図形を完全に囲んでいるかどうかをテストする Contains メソッドを追加しました (「追加しようとしました」と読みます)。サイズの異なる 2 つの形状は Intersect では機能しますが、Contains では機能しないため、二重ディスパッチは失敗します。shape_oneは大きな円であり、 でshape_two完全に囲まれた小さな円shape_oneです。呼び出しshape_one.Contains(shape_two)は true を返しますが、shape_two.Contains(shape_one)false を返します。

このタイプのシナリオで二重ディスパッチを実装する方法はありますか?

(質問の理解を深めるために、タイトルの編集をお勧めします...)

二重ディスパッチを使用した 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());
}
4

1 に答える 1

0

プッシュによって解決されたのは、基本クラスまでの 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
于 2013-02-05T00:01:55.473 に答える