2016-12-28 15 views
0

私はモノポリーをC++で実装しています。私は抽象的なスーパークラスBoardSquare(その唯一のプロパティは四角形の名前です)を扱っています。ゲームの正方形のタイプに応じて様々なサブクラスがあります(プロパティ、チャンスなど)。スーパークラスオブジェクトの配列からサブクラスメソッドを呼び出す

ボードアレイと四角は、その種類が異なるように、私はBoardSquareポインタの配列宣言していますように

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

と:

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

や種類に応じて、各項目を移入し続けています。

Propertyは、例えば、getPrice()のような特定の方法を持っています。しかし

board[1]->getPrice() 

がエラーに

「クラスGameSquare」を与え実行すると、ポインタはまだGameSquareとして扱われていることを私に伝えます

「getPrice」という名前のメンバーを持っていません。これを回避する方法はありますか?おそらくタイプキャストですか?それともより洗練された実装ですか?

+0

インスタンスの型をチェックして、基本型を呼び出すためにサブ型にキャストできるようにする必要があります。 – Piou

+1

@Piou構文の例を教えてください。例えば、私は 'board [1]'がプロパティであることを知っているので、 '((Property *)board [1]) - > getPrice()'を実行できますか? –

+0

もう一つの解決策は 'GameSquare'クラスに' getPrice'という仮想メソッドを実装して-1を返し、 '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:いくつかのコメンターが提案したように、あなたはGameSquareクラスにメソッドを追加することができgetPrice() GameSquare

にgetPrice()を追加します。正方形がPropertyでない場合は、0を返すだけです。これにより、何かがPropertyか他のものかを確認することができます。

1

あなたは確かにあなたが求めていることをすることができますが、あなたがこれをしなければならないという事実は、OO設計ルールを破っていることを意味します。

私は、購入、住宅ローン、カード取得、パス・ゴーイングなど、プレイヤーがその上で実行できる行動に関して、各広場を調べることをお勧めします。プレーヤーが正方形に着陸すると、自動的に動作することがあります。いくつかはGUIで表示されます。

この方法では、正方形に価格が付いていることを知る必要はありません。プレーヤーに可能な購入アクションを提供するだけで、アクションはそれがプロパティであることが分かります。プロパティがプレーヤーによって所有されている場合、それは今 "ビルハウス"アクションを取得します。等々。

正方形には、vector<ActionPtr> getActionsFor(PlayerPtr player)の行に沿った方法があります。

+0

私はこの解決策が好きです。それはC#またはJSで実装する方法ですが、私は提案するほど熟練していませんでした。(typeid(board [i])== "CommunityChest" C++でのコードスニペット – Piou

関連する問題