2011-08-24 166 views
9

好吧,我一直在研究一個遊戲引擎,並且遇到了問題......目前我有一個類的層次結構(圖像 - >動畫 - >對象),所有這些都有一個方法如果我使用新關鍵字聲明派生類繼承混亂

,或者靜態地,我得到所期望的結果::get_type(),我有這個問題

object instance; 
cout << instance.get_type(); //returns an int value 

object* pointer = new(object); 
cout << pointer->get_type(); 

從上面的代碼中,控制檯輸出3。該方法在對象中聲明爲:

圖片類:

class image{ 
public: 
    virtual int get_type(); 
}; 

int object::get_type(){ 
    return 1; 
} 

動畫類:

class animation: public image{ 
public: 
    virtual int get_type(); 
}; 

int animation::get_type(){ 
    return 2; 
} 

對象類:

class object: public animation{ 
public: 
    virtual int get_type(); 
}; 

int object::get_type(){ 
    return 3; 
} 

現在,當我這樣做問題就出現了

object* t = &object(); 
cout << t->get_type(); 

結果是現在1

如果我刪除從對象類的類聲明的虛擬關鍵字,它的作品,因爲我希望(代碼最後一位返回3)

問題:如何在不使用新關鍵字的情況下利用對象*指針中的虛擬方法?原因是,我填補了矢量與指向這些對象,並創建爲我加入他們,所以我希望能夠做一些類似如下:

vector<object*> objects; //not imgs or animations 
for (int a = 0; a < 20; a++){ 
    objects.push_back(&object()); 
} 

而有任何對象[X ] - > get_type();返回正確的類類型。原因是我在我的遊戲中使用的事件系統需要發起類的類型...

TLDR;我真的很厭惡繼承,你能幫忙嗎?

+2

這個新手問題很好。 – sharptooth

回答

7

這是因爲這兩個構造和析構函數已經在你的代碼運行:

object* t = &object(); 
cout << t->get_type(); 

&object()創建(匿名的,臨時的)目標,立即自毀它(因爲它是暫時的),然後再轉讓現在銷燬的對象的地址爲t。 (如果你把警告級別達到足夠高,你的編譯器可能會警告你這個表情。)

嘗試創建過程中的時間堅持圍繞一個對象,你正在使用它:

object my_object(); 
object *t = &my_object; 
cout << t->get_type(); 

當你」重新使用非虛函數,在編譯時使用指針類型t來確定調用哪個方法。當你使用虛擬函數時,在虛擬調度期間在運行時使用對象內部的信息來決定調用哪個函數。由於你的對象在調用時沒有被正確構造(因爲它已經被破壞了),結果是嚴格未定義的,但最終調用了錯誤的函數。

+0

那麼我該如何創建一個可變數量的這些對象?我堅持創建它們並明確刪除它們嗎? – Avlagrath

+0

「由於您的對象構造不正確,結果嚴格未定義,但最終會調用錯誤的函數。」 我該如何去正確創建對象? – Avlagrath

+4

你可以用'new object()'在堆上創建新的。通常,當你在堆上分配對象時,多態性效果最好。 –