2016-05-17 97 views
0

我正在與類 的RPG遊戲工作我創建了一個結構調用字符與存儲實例的ActionList *。 GeneralPlayer是一個類,其中仍然有許多其他玩家類繼承它。 這是我的頭文件:類的指針void *

class Battle 
{ 
public: 
     struct Character 
     { 
     char type;//monster or player? 
     bool alive; 
     void*instance;//pointer to instance 
     }; 
     Battle(GeneralPlayer*,AbstractMonster*,int,int,int);  
     Battle(GeneralPlayer*, AbstractMonster*, int, int); 
private: 
     Character *ActionList; 
}; 

我試圖轉換GeneralPlayer *爲void *。然而,似乎代碼不工作,因爲我認爲。 P和M是這些玩家類的指針數組。

Battle::Battle(GeneralPlayer*P, AbstractMonster*M, int a, int b, int c) 
{ 
    a = numP; 
    b = numM; 
    c = turn_limit; 
    ActionList = new Character[numP + numM]; 
    P = new GeneralPlayer[numP]; 
    for (int i = 0; i < numP; i++) 
    { 
     ActionList[i] = static_cast<void*>(P[i]); 
     ActionList[i].type = 'p'; 
    } 
    for (int i = numP; i < numP+numM; i++) 
    { 
     ActionList[i] = static_cast<void*>(M[i]); 
     ActionList[i].type = 'm'; 
    } 
} 

它一直顯示錯誤C2440。我希望可以解決我的問題,任何人都可以幫助你。

+3

'P [i]'不是'GeneralPlayer *',它是'GeneralPlayer'。 – songyuanyao

+0

你的意思是說,在你調用該函數之後,你以'P'傳遞的變量似乎沒有被初始化?請嘗試詳細說明,也請嘗試創建[最小,完整和可驗證的示例](http://stackoverflow.com/help/mcve)向我們展示。 –

+0

@songyuanyao對不起,我還是初學者。如果P [i]不是GeneralPlayer *,那麼我應該使用什麼? –

回答

4

這裏的一個問題是,Character結構也不GenericPlayerAbstractMonster的父母。看來,Character::instance成員應指向玩家或怪物,這意味着你的代碼應該是這樣

ActionList[i].type = 'p'; 
ActionList[i].alive = true; 
ActionList[i].instance = &P[i]; 

這是假設的球員名單已經由Battle構造函數的調用初始化,然後你不應該分配一個新的球員陣列,所以P = new GenericPlayer[numP];聲明應該被刪除。

需要注意的是,像你這樣的一個「通用指針」(什麼是void *),然後是一個成員說它真的指向什麼類型被認爲是不好的設計。相反,你會爲怪物和玩家建立一個共同的基類,並使用一個指向它的指針。然後正確使用多態性virtual成員函數,您不需要type字段。然後很容易重構代碼以使用一些其他方法來告訴玩家或怪物是否存活,然後根本不需要Battle::Character類,並且可以使用指向公共基類的指針數組相反,從而簡化了代碼,這對於可維護性來說非常有利。


還有一些其他問題的代碼,你表現出來,事情將在運行後會出現問題。

的一個問題是,在循環遍歷怪物,你初始化onumP和環路最多numP + numM,但是如果陣列M不包含numP + numM元素,你會去出界。

相反,我建議你做例如

for (int i = 0; i < numM; i++) 
{ 
    ActionList[i + numP].type = 'm'; 
    ActionList[i + numP].alive = true; 
    ActionList[i + numP].instance = &M[i]; 
} 
+0

我的功能是將其他類的指針傳遞給它 –

+0

@ShiYiLee假設你有一個函數'void f(int a){a + = 5; }'。現在當你調用這個函數時,說'f(some_int_variable)',你會期望'some_int_variable'改變嗎?這與'Battle'構造函數中的指針變量'P'是一樣的,在函數'P'內是一個* local *變量,對'P'的所有修改只會在函數內部存在。當你賦值給'P'('P = new ...')時,它只在函數內部,你在調用中使用的變量不會被修改。 –

+0

@ShiYiLee在我以前的評論中討論的問題可以通過引用'P'來解決,改變非常簡單:'Battle(GenericPlayer *&P,...)'。在那裏添加符號('&')使得'P'成爲一個指向'GenericPlayer'的指針。 –

5

您正在嘗試將對象轉換爲指針,請使用運算符來獲取指針。

ActionList[i] = (void*)&P[i]; 
ActionList[i] = (void*)&M[i]; 
+0

你不需要明確的(甚至是c風格)強制轉換。任何數據指針類型可隱式轉換爲void *' – StoryTeller

+0

此外,Character * ActionList應該可能是數據類型Character **,Character ** ActionList = new Character * [numP + numM]; –

+0

這是真的,但不回答這個問題('ActionList [i] .instance =(void *)&P[i];'會)或解決OP的問題。另外爲什麼你想放棄編譯器可以爲你做的所有類型檢查善良? – user4581301