2011-02-28 151 views
1

我目前正在研究一個學校項目的業餘物理引擎,但由於C++問題而卡住了。該設置是如下:有關繼承和鑄造的C++問題

我有三個不同的類:

  • 剛體(摘要)
  • 球(來自剛體繼承)
  • CustomRigidBody(來自剛體繼承和代表多角體)

我需要檢查是否碰撞發生在一對具有兩個同名方法的物體之間。一個用於檢查與Sphere的聯繫,而另一個用於檢查與CustomRigidBody的聯繫。有幾種可能的情景(球體/球體碰撞,球體/自定義碰撞等),所以這兩種方法都是在所有這些類中定義的。

在剛體,它們是抽象的:

virtual bool isCollidingWith(Sphere* s_p) = 0; 
virtual bool isCollidingWith(CustomRigidBody* rb_p) = 0; 

但不是在球:

bool isCollidingWith(Sphere* s_p); 
bool isCollidingWith(CustomRigidBody* rb_p); 

也不在CustomRigidBody:

bool isCollidingWith(Sphere* s_p); 
bool isCollidingWith(CustomRigidBody* rb_p); 

在我的主程序,我有一個std::vector<RigidBody*>包含指向RigidBody(超類)的指針,我需要檢查碰撞吐溫對象通過對通過調用類似:

for(int i = 1; i < this->bodies_p.size(); ++i) 
    for(int j = 0; j < i; ++j) 
     if(this->bodies_p[i]->isCollidingWith(this->bodies_p[j])) 
      std::cout << " COLLISION BETWEEN " << i << " AND " << j << std::endl; 

我的印象是,C++將與確定的,但我得到了以下錯誤消息:

Engine.cc:35: error: no matching function for call to ‘RigidBody::isCollidingWith(RigidBody*&)’ 
RigidBody.h:53: note: candidates are: virtual bool RigidBody::isCollidingWith(Sphere*) 
RigidBody.h:54: note:     virtual bool  RigidBody::isCollidingWith(CustomRigidBody*) 

我的猜測是,它有這樣做的事實,體的向量包含指向RigidBody的指針,它們不會自動轉換爲Sphere *或CustomRigidBody *,但我不知道如何解決問題。

謝謝您的幫助;)

回答

4

此問題是由Double Dispatch解決。從本質上講,你需要另一個重載增加RigidBody及其派生類:

bool isCollidingWith(RigidBody* rb_p) = 0; 

在派生類,例如Sphere,執行將是這樣的:

bool Sphere::isCollidingWith(RigidBody* rb_p) 
{ 
    return rb_p->isCollidingWith(this); 
} 

這工作,因爲第一次isCollidingWith被稱爲(在循環)(通過虛方法),中isCollidingWith(RigidBody*)從正確的派生類的版本被調用。然後,在Sphere::isCollidingWith(RigidBody*)中,通過虛擬方法使用正確的派生類。但是,這一次,thisSphere*,所以調用的超載是isCollidingWith(Sphere*)版本。

換句話說:

  1. 在你的循環:

    this->bodies_p[i]->isCollidingWith(this->bodies_p[j]) 
    

    會打電話或者Sphere::isCollidingWith(RigidBody*)CustomRigidBody::isCollidingWith(RigidBody*),根據實際類型的bodies_p[i]。假設這是一個Sphere,然後我們得到

  2. Sphere::isCollidingWith(RigidBody* rb_p)

    return rb_p->isCollidingWith(this); 
    

    這就要求無論是Sphere::isCollidingWith(Sphere*)CustomRigidBody::isCollidingWith(Sphere*),根據實際類型的rb_p

+1

不錯的'把戲'。甚至停止添加我的答案,因爲這比我的解決方案好得多。 – RedX 2011-02-28 22:52:57

+1

謝謝你的回答和詳細的解釋!您粘貼的維基百科鏈接甚至引用物理模擬作爲使用雙派遣的特徵情況之一= D – megamoustache 2011-02-28 23:00:40

+0

@RedX:在這裏相同。上帝,我愛StackOverflow。 :d – suszterpatt 2011-02-28 23:02:30