2016-12-28 73 views
0

我在C++中實現遊戲壟斷。我正在處理一個抽象超類BoardSquare(其唯一的屬性是方形名稱),根據遊戲平方的類型(不管它是屬性,機會等),各種子類都可以處理。從超類對象數組調用子類方法

現在因爲我想表示板作爲陣列和正方形中它們的類型不同,我已經聲明的BoardSquare指針的數組:

GameSquare** board = new GameSquare*[40]; 

並繼續填充取決於類型中的每個條目:

board[1] = new Property("Old Kent Road", 0); 
board[2] = new CommunityChest(); 
board[3] = new Property("Whitechapel Road", 0); 

等。

現在Property,例如,具有特定的方法,如getPrice()。但運行

board[1]->getPrice() 

給出了錯誤

「類GameSquare」沒有名爲成員「用getPrice」

告訴我,指針仍然被視爲GameSquare。有沒有解決的辦法?可能類型化?或者更完美的實現呢?

+0

您需要檢查實例的類型才能將其轉換爲子類型以調用基礎方法。 – Piou

+1

@Piou你能給我一個句法的例子嗎?例如我知道'board [1]'是屬性,所以我可以運行'((Property *)board [1]) - > getPrice()'? –

+0

另一個解決方案是在'GameSquare'類中實現一個返回-1的虛擬方法'getPrice',在'Property'中覆蓋它以返回傳遞給構造函數的價格。然後在顯示邏輯中,您只需檢查價格是否大於0即可顯示信息。 – Piou

回答

2

這是一個很好的例子object slicing

建議1:動態低迷現狀,以防止它

一種方法是添加以下內容:

Property *b1 = dynamic_cast<Property*>(board[index]); 
if (b1) 
{ 
    int b = b1->getPrice(); // Or whatever getPrice() returns; 
} 

但是,你必須嘗試動態低垂的每個子類(PropertyCommunityChest,等等),這可能會使代碼看起來很笨重。

建議2:添加用getPrice()來GameSquare

正如一些評論者建議,可以將方法getPrice()添加到GameSquare類。如果廣場不是Property,只需返回0。這可以讓你檢查是否是Property或其他東西。

1

你當然可以做你要求的東西,但事實是你必須這樣做意味着你打破了面向對象的設計規則。

我會建議在玩家可以對其執行的操作方面看每個廣場,例如購買,抵押,獲取卡,傳遞去。當玩家登上廣場時,某些動作可能會自動進行。一些可能會在GUI中呈現。

這樣,您不必知道廣場有價格 - 您只需提供玩家可能的購買動作,而動作就知道它是一個屬性。如果該財產屬於玩家所有,那麼它現在將獲得「建造房屋」的行爲。等等。

一個正方形將有一個沿着vector<ActionPtr> getActionsFor(PlayerPtr player)的方法。

+0

我喜歡這個解決方案,這就是我如何在C#或JS中實現它,但是我沒有足夠的技巧去提出C++中的代碼片段 – Piou