2011-09-20 176 views
0

我對C++比較新,我一直在使用OpenGL開發基本的3D渲染引擎。我有以下問題: 我有一個名爲GeomEntity的類,它是所有幾何圖元的基類。我有另一個名爲DefaultMaterial的類,它是所有材質的基類(由不同類型的着色器程序組成)。因爲我將有許多類型的材質,如:ColorMaterial,TextureMaterial,AnimatedMaterial等等,我需要放置參考GeomEntity類的材料,以便從主應用程序,我可以設置任何使用該功能的材料:C++多態性和類型鑄造

void GeomEntity ::addMaterial (const DefaultMaterial *mat){ 

     material=mat;////material is the member variable pointer of type DefaultMaterial 

    } 

但事實是,雖然所有的這些材料是從DefaultMaterial派生的,它們都有獨特的方法,如果我將它們默認引用到DefaultMaterial的變量,我不能觸發它們。 因此,例如在主應用程序:

Sphere sphere; 
    .... 
    sphere.addMaterial(&animMaterial);///of type AnimatedMaterial 
    sphere.material->interpolateColor(timerSinceStart); 
    ///doesn't happen anything as the sphere.material is 
    /// of type DefaultMaterial that has no interpolateColor() method 

我知道我可以使用模板或石膏,但我想聽到這種多態性在C++。在Java中的最佳做法或C#我真的使用這樣的:

((AnimatedMaterial)sphere.material).interpolateColor(timerSinceStart); 

回答

2

在C++中,你可以做到這一點使用dynamic_cast的,那就是我相信C#功能最接近的等效:

AnimatedMaterial* panim = dynamic_cast<AnimatedMaterial*>(sphere.material); 
if(panim) 
    panim->interpolateColor(timerSinceStart); 
+1

我認爲這與我所瞭解的託管語言最接近。 –

1

爲什麼不能簡單地用:

Sphere sphere; 
//.... 
sphere.addMaterial(*animMaterial); //of type AnimatedMaterial 
animMaterial->interpolateColor(timerSinceStart); 

因爲animMaterial已經正確類型的?

+0

的GeomEntity內部的材料屬性是不具有interpolateColor()方法 –

+0

@Ben福格特,你確定通用DefaultMaterial類型的?內部材料也可以作爲參考(仍然很奇怪,但是..)。在材質上調用'interpolateColor'應該可以在函數外正常工作。 @邁克爾,我不知道你在說什麼。 – Blindy

+0

問題發生變化後,這似乎是正確的答案。 –

2

你可以施放,它看起來像:

static_cast<AnimatedMaterial*>(sphere.material)->interpolateColor(...); 

但使用Blindy的方式,它的清潔。


原來的答覆爲無效的問題編輯:

你說:

//material is the member variable pointer of type DefaultMaterial 

在你使用它的方式來看,它實際上不是一個指針。如果是的話,一切都會正常工作。

void GeomEntity::addMaterial(DefaultMaterial *mat) 
{ 
    material = mat; // material is the member variable pointer of type DefaultMaterial* 
} 

當傳遞多態對象時,應該使用指針而不是引用。

+0

對不起,這是一個錯字。問題不在於指針,而是當我們的屬性數據類型是基類時,如何觸發派生類中的方法? –

+2

@Michael IV,我不同意,真正的問題是*你爲什麼要這麼做*?一個正確建模的OOP類層次結構不應該關心其實例的類型,它應該僅以基類作爲接口來處理自身。 – Blindy

+0

@布林迪,你說得對,你說我不需要投射,如果材料引用了包含該方法的正確類>>? –

2

如果您確信sphere.material指向具有interpolateColor與之相關聯的方法的對象,你可以使用static_cast(如果有疑問,那麼你會使用dynamic_cast)。所以假設AnimatedMaterial類有interpolateColor方法:

static_cast<AnimatedMaterial*>(sphere.material)->interpolateColor(timerSinceStart);