C++ 设计问题,基类知道它的派生

C++ 设计问题,基类知道它的派生,c++,base-class,C++,Base Class,基本上我有一个叫做几何的基类,还有一些导数,比如点,多边形等等 几何体实现了如下方法: Geometry* intersection(Geometry* other) { Geometry* inter = compute_intersection(this, other); if (inter is a polygon) return new Polygon(inter); if (inter is a point) r

基本上我有一个叫做几何的基类,还有一些导数,比如点,多边形等等

几何体实现了如下方法:

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);
} 
当我在我的程序中计算两个几何体的交集时,我得到一个几何体*并且我可以动态地将它转换为任何实际的几何体

这个设计好吗?我认为,可能错误的是,每次我计算一个交叉口时,我都必须检查实型,并且动态地抛出结果,这可能会很慢。但我认为主要的问题是,在这种设计中,几何体必须知道它的导数点,多段线?等等


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

为什么需要为返回的对象构造一个新对象,不能直接返回它吗?如果不能,只需在每个派生类中实现一个附加方法,将计算交叉的结果包装到新对象中,并调用此新方法而不是几何体中的计算交叉


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

为什么需要为返回的对象构造一个新对象,不能直接返回它吗?如果不能,只需在每个派生类中实现一个附加方法,将计算交叉的结果包装到新对象中,并调用此新方法而不是几何体中的计算交叉


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

如果您发现自己需要根据继承的类型新建以复制对象,那么您可以通过实现一个返回对象副本的克隆函数来使用:

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

这可以从交叉点函数调用。

如果您发现自己需要根据继承的类型新建以复制对象,则可以通过实现一个克隆函数来使用,该函数返回对象的副本:

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

这可以从交集函数调用。

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

首先,我不太喜欢获取/设置东西的函数。我更感兴趣的是告诉objects为我做点什么

其次,在这种情况下,您试图实现多重分派,即双重分派。这就是您想要的行为取决于多个对象的类型的地方

我的普通咒语“封装,封装,封装”引导我实现以下想法:

封装您想要对交叉点执行的操作,例如:。 将其区域放入电子表格单元格 将几何图形点添加到显示列表 封装一种类型的分派给另一种类型 查看访客模式 封装将行为应用于交叉点
就我而言,这里有两个问题

首先,我不太喜欢获取/设置东西的函数。我更感兴趣的是告诉objects为我做点什么

其次,在这种情况下,您试图实现多重分派,即双重分派。这就是您想要的行为取决于多个对象的类型的地方

我的普通咒语“封装,封装,封装”引导我实现以下想法:

封装您想要对交叉点执行的操作,例如:。 将其区域放入电子表格单元格 将几何图形点添加到显示列表 封装一种类型的分派给另一种类型 查看访客模式 封装将行为应用于交叉点 或许您可以使用:

或许您可以使用:


您的问题的名称为:多分派或多方法。据我所知,C++中没有真正的好答案。Andrei Alexandrescu对此问题的详细讨论如下:


我建议你买这本书,它的价格是物有所值的。

你的问题被称为:多重分派或多重方法。据我所知,C++中没有真正的好答案。Andrei Alexandrescu对此问题的详细讨论如下:


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

你需要一个抽象的工厂设计模式。@Als它不是纯工厂,但他已经实现了……你的代码真的是这样吗?我有一种感觉,你还没有讲述整个故事……只需使用一个返回几何体的虚拟函数*并在compute_intersection的返回值上调用它。这样,用于各种派生类的该函数的版本可以根据需要返回指向点或多边形的指针。多边形、点和其他几何体派生是否实现几何体接口中不存在的方法?您需要抽象工厂设计模式。@它不是纯工厂,但他已经实现了……这真的是你的代码吗?我有一种感觉,你还没有讲完整的故事…只需使用一个返回几何体的虚拟函数*然后 在compute_交集的返回值上voke它。这样,各种派生类的函数版本可以根据需要返回指向点或多边形的指针。多边形、点和其他几何体派生是否实现几何体接口中不存在的方法?