从超类对象数组中调用子类方法

时间:2016-12-28 17:43:40

标签: c++ class oop abstract-class abstract

我正在用C ++实现游戏 Monopoly 。我正在处理一个抽象超类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()

给出错误

  

'class GameSquare'没有名为'getPrice'的成员

告诉我指针仍被视为GameSquare。有没有解决的办法?也许是在拍摄吗?还是一个更优雅的实现呢?

2 个答案:

答案 0 :(得分: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 :(得分:1)

你当然可以做你要求的事情,但事实上你必须这样做意味着你违反了OO设计规则。

我建议根据玩家可以对其执行的操作来查看每个方块,例如买入,抵押,获取卡,传递去。当玩家落在广场上时,某些动作可能是自动的。有些可能会在GUI中显示。

通过这种方式,您不必知道广场有价格 - 您只需向玩家提供可能的购买行动,而行动就知道它是一个属性。如果该物业归玩家所有,那么它现在可以建造房屋&#34;行动。等等。

一个正方形将有vector<ActionPtr> getActionsFor(PlayerPtr player)的方法。