基本上我有一个名为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);
}
当我计算程序中两个几何的交集时,我得到一个Geometry*
,我可以dynamic_cast
到它的真实状态。
这是一个好的设计吗?我认为可能是错误的是每次计算交集时都必须检查实数类型并且动态调整结果(可能很慢)。但我认为主要的问题是,使用这种设计,Geometry
必须知道它的衍生物(Point,Polyline?etc ......)。
什么是避免这些问题的好方法?
答案 0 :(得分:0)
为什么你需要构造一个返回对象的新对象,你能不能直接返回它?如果你不能,只需在每个衍生类中实现一个额外的方法,将compute_intersection
的结果包装在一个新对象中,并在compute_intersection
中调用这个新方法而不是Geometry
。
在我的回答中,我假设唯一可能的情况:compute_intersection
是抽象的,每个派生类都实现它。
答案 1 :(得分:0)
如果你发现自己需要根据继承的类型来复制对象,那么你可以使用virtual copy constructors,通过实现一个返回对象副本的clone()函数:
virtual Obj* Obj::clone() const { return new Obj(*this); }
可以从intersection()函数调用它。
答案 2 :(得分:0)
就我而言,这里有两个问题。
首先,我并不关心获取/设置事物的功能。我更有兴趣告诉对象为我做点什么。
其次,您正在尝试实现多个调度(在本例中为双调度)。这是您需要的行为取决于多个对象的类型。
我正常的封装,封装,封装的口头禅引导我走向以下想法:
答案 3 :(得分: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
}
答案 4 :(得分:0)
您的问题名称为multiple dispatch
或multi methods
。据我所知,在C ++中这个问题没有真正好的答案。 Andrei Alexandrescu对这个问题进行了很好的讨论:
我建议你买这本书值得它的价值。