2012-04-25 23 views
2

基本上我有稱爲Geometry基類,以及一些衍生物如PointPolygon等...設計問題,基類知道它的衍生物

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?等等)。

什麼可能是一個很好的解決方案,以避免這些問題?

+0

您需要抽象工廠設計模式。 – 2012-04-25 07:35:18

+0

@Als它不是純粹的工廠,但他已經實現了它... – 2012-04-25 07:49:29

+0

這真的是你的代碼的樣子嗎?我有一種感覺,你沒有講完整個故事...... – 2012-04-25 07:52:17

回答

0

爲什麼你需要構造一個返回對象的新對象,你不能直接返回它嗎?如果不能,只需在每個派生類中實現一個附加方法,將compute_intersection的結果包裝到一個新對象中,然後調用此新方法而不是compute_intersectionGeometry

在我的答案我假設唯一可能的情況:compute_intersection是抽象的,每個派生類實現它。

0

如果你發現自己需要新的根據遺傳型複製的對象,那麼你可以使用virtual copy constructors,通過實施返回對象的一個​​副本的克隆()函數:

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

這可能是從你的intersection()函數調用。

0

就我而言,這裏有兩個問題。

首先,我不太關心獲取/設置事物的函數。我更感興趣的是告訴物體爲我做些事情。

其次,你正試圖實現多派遣(在這種情況下雙派遣)。這就是你想要的行爲取決於多個對象的類型。

封裝的正常口頭禪,封裝,封裝引導我走向了以下思路:

  • 封裝你想例如與路口做什麼
    • 將其面積到電子表格單元格
    • 添加幾何點的顯示列表
  • 封裝給出另一種類型的
    • 查找到訪問者模式
  • 一種類型的調度
  • 將行爲應用於路口的封裝
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 
} 
0

您的問題是已知的名義下:multiple dispatchmulti methods。就我所知,在C++中沒有真正的好問題。由安德烈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=onepage&q&f=false

,我建議你買的書是值得它的價格。