【问题标题】:How to use dynamic polymorphism in this case?在这种情况下如何使用动态多态性?
【发布时间】:2014-04-23 19:19:33
【问题描述】:

我有以下简单的类来模拟点集。

struct Shape
{
    virtual bool contains(point x) const = 0;
}
typedef std::shared_ptr<Shape> ShapePtr;

struct Intersection : public Shape
{ 
    Intersection(ShapePtr shape1, ShapePtr shape2):
                 shape1_(shape1),shape2_(shape2){}
    ShapePtr shape1_;
    ShapePtr shape2_;
    bool contains(point x) const {return shape1_->contains(x) && 
                                         shape2_->contains(x);}
}

ShapePtr intersect(ShapePtr shape1, ShapePtr shape2)
{
    return std::make_shared<Intersection>(shape1, shape2);
}

到目前为止一切顺利。但是假设我添加了一个Shape,即Rectangle

struct Rectangle : public Shape 
{
     double x1_,x2_,y1_,y2_;
     ...
}

原始代码运行良好,但可以利用两个矩形的交点是一个矩形这一事实来改进它。也就是说,intersect 函数可以返回一个指向Rectangle 的指针。

当我添加更复杂的形状时,我应该如何修改此代码以适应更多此类情况?

【问题讨论】:

    标签: c++ inheritance coding-style polymorphism


    【解决方案1】:

    您可能需要 MultiMethods。具体来说,您希望在实际类型上进行运行时调度。

    这是一篇关于他们的帖子:"type-switch" construct in C++11

    顺便说一句:由于您总是使用 std::shared_ptr 与派生自 Shape 的所有对象,因此请考虑使用 std::enable_shared_from_this

    另外,您可能想要创建一个边界框并检查空交叉点。作为添加的优化,添加一个空形状(静态 Singleton 对象)。 Shape 本身就是一个很好的类型。

    【讨论】:

    • 感谢您提供的所有有用建议!我正在尝试了解您给我的解决方案。你似乎在这种事情上有经验。有没有类似代码的开源库可以学习?
    • 所以你建议我每次在某些特定形状组合上添加优化时修改intersect函数?
    • 我不知道。我只是应用从动态语言导入到静态领域的 OO 口头禅和概念。
    • AFAIK,在 C++ 中没有办法获得一个函数对模板元编程的所有重载列表。这将使您能够保持intersect-函数的源代码相同,尽管它不会改变重新编译的需要。顺便说一句:在你整合了enable_shared_from_this 之后,我总是会得到Shape*-arguments for intersect
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-11-26
    • 2013-05-22
    • 1970-01-01
    • 2018-01-25
    • 2018-03-21
    • 2023-03-24
    • 2022-01-23
    相关资源
    最近更新 更多