2

基本上我有一个名为 的基类Geometry,以及一些派生类,例如Point,Polygon等...

Geometry实现这样的方法交集:

Geometry* intersection(Geometry* other)
{
     Geometry* inter = compute_intersection(this, other); 

     if (inter is a polygon) 
         return new Polygon(inter);

    if (inter is a point) 
         return new Point(inter);
} 

当我在我的程序中计算两个几何图形的交集时,我得到 aGeometry*并且我可以dynamic_cast将它变成任何它真正的样子。

这是一个好的设计吗?我认为,可能错误的是,每次计算交集时我都必须检查真实类型,然后 dynamic_cast 结果(这可能很慢)。但我认为主要问题是这种设计,Geometry必须知道它的导数(点,折线?等......)。

有什么好的解决方案可以避免这些问题?

4

5 回答 5

0

为什么需要构造返回对象的新对象,不能直接返回吗?如果不能,只需在每个派生类中实现一个额外的方法,将结果包装compute_intersection在一个新对象中,然后调用这个新方法而不是compute_intersectionin Geometry

在我的回答中,我假设唯一可能的情况:compute_intersection是抽象的,并且每个派生类都实现了它。

于 2012-04-25T07:48:11.437 回答
0

也许你可以使用boost::variant

typedef boost::variant<Point, Polygon/*, and other...*/> Geometry_Variants;

Geometry_Variants intersection(Geometry_Variants const& other)
{
    // compute the intersection and return Point or Polygon
}
于 2012-04-25T10:11:07.667 回答
0

您的问题以名称为人所知:multiple dispatchmulti methods。据我所知,在 C++ 中这个问题没有真正好的答案。Andrei Alexandrescu 对这个问题的一个很好的讨论在这里:

http://books.google.fr/books?id=aJ1av7UFBPwC&pg=PA263&lpg=PA295&dq=modern+c%2B%2B+design+multiple+dispatch&source=bl&ots=YRdIZrWiaV&sig=2Vj0Blst_jmhMCAZIJ8gUiG_pl4&hl=fr&sa=X&ei=082XT86RHNS18QPW7f3mBQ&ved=0CCYQ6AEwAA#v=一页&q&f=false

我建议你买这本书,它物有所值。

于 2012-04-25T10:14:46.053 回答
0

如果你发现自己需要根据继承的类型来 new 来复制对象,那么你可以使用虚拟复制构造函数,通过实现一个返回对象副本的 clone() 函数:

virtual Obj* Obj::clone() const { return new Obj(*this); }

这可以从您的 intersection() 函数中调用。

于 2012-04-25T08:21:01.307 回答
0

就我而言,这里有两个问题。

首先,我不太关心获取/设置事物的功能。我对告诉对象为我做某事更感兴趣。

其次,您正在尝试实现多分派(在本例中为双分派)。这是您想要的行为取决于多个对象的类型的地方。

我的封装、封装、封装的正常口头禅引导我走向以下想法:

  • 封装你想对交叉点做的事情,例如
    • 将其区域放入电子表格单元格
    • 将几何点添加到显示列表
  • 封装给定另一种类型的一种类型的调度
    • 查看访客模式
  • 封装将行为应用于交叉点
于 2012-04-25T09:05:29.107 回答