从超类对象数组调用子类方法 我在C++中实现了游戏专卖。我处理的是一个抽象的超类BoardSquare(其唯一属性是square名称),根据游戏square的类型(是否是属性、机会等)有不同的子类

从超类对象数组调用子类方法 我在C++中实现了游戏专卖。我处理的是一个抽象的超类BoardSquare(其唯一属性是square名称),根据游戏square的类型(是否是属性、机会等)有不同的子类,c++,class,oop,abstract-class,abstract,C++,Class,Oop,Abstract Class,Abstract,现在,由于我想将电路板表示为一个数组,并且正方形的类型不同,因此我声明了一个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); 等等 例如,现在Pr

现在,由于我想将电路板表示为一个数组,并且正方形的类型不同,因此我声明了一个
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。有办法解决这个问题吗?也许是打字?还是一个更优雅的实现

这是一个很好的例子

建议1:动态下行 防止这种情况的一种方法是添加以下内容:

Property *b1 = dynamic_cast<Property*>(board[index]);
if (b1)
{
    int b = b1->getPrice(); // Or whatever getPrice() returns;
}
Property*b1=dynamic_cast(董事会[索引]);
如果(b1)
{
int b=b1->getPrice();//或getPrice()返回的任何内容;
}
但是,您必须为每个子类尝试动态向下转换(
Property
CommunityChest
,等等),这可能会使代码看起来很笨拙

建议2:将getPrice()添加到GameSquare
正如一些评论者所建议的,您可以将方法
getPrice()
添加到
GameSquare
类中。如果正方形不是
属性
,只需返回
0
。这允许您检查某个属性是
属性还是其他属性。

这是一个很好的示例

建议1:动态下行 防止这种情况的一种方法是添加以下内容:

Property *b1 = dynamic_cast<Property*>(board[index]);
if (b1)
{
    int b = b1->getPrice(); // Or whatever getPrice() returns;
}
Property*b1=dynamic_cast(董事会[索引]);
如果(b1)
{
int b=b1->getPrice();//或getPrice()返回的任何内容;
}
但是,您必须为每个子类尝试动态向下转换(
Property
CommunityChest
,等等),这可能会使代码看起来很笨拙

建议2:将getPrice()添加到GameSquare
正如一些评论者所建议的,您可以将方法
getPrice()
添加到
GameSquare
类中。如果正方形不是
属性
,只需返回
0
。这允许您检查某个属性是
属性还是其他属性。

您当然可以按照自己的要求去做,但您必须这样做的事实意味着您违反了OO设计规则

我建议你看看每一个方块,看看玩家可以在上面做什么,比如买,抵押,拿牌,传球。当玩家降落在广场上时,某些动作可能是自动的。有些可以在GUI中显示

这样,你就不必知道一个正方形是有价格的——你只需要给玩家提供可能的购买动作,而这个动作就知道这是一个属性。如果该财产归玩家所有,它现在将获得“建造房屋”操作。等等


一个正方形会有一个类似于向量getActionsFor(playerptrplayer)

的方法,你当然可以按照你的要求去做,但是你必须这样做的事实意味着你违反了OO设计规则

我建议你看看每一个方块,看看玩家可以在上面做什么,比如买,抵押,拿牌,传球。当玩家降落在广场上时,某些动作可能是自动的。有些可以在GUI中显示

这样,你就不必知道一个正方形是有价格的——你只需要给玩家提供可能的购买动作,而这个动作就知道这是一个属性。如果该财产归玩家所有,它现在将获得“建造房屋”操作。等等


一个正方形将有一个方法,它的行与(PlayerPtr player)

的向量getactions类似,您需要检查实例的类型,以便能够将其转换为子类型以调用基础方法。@p您能给我一个语法示例吗?例如,我知道
board[1]
是一个属性,所以我可以运行
((property*)board[1])->getPrice()
?另一个解决方案是在
GameSquare
类中实现一个返回-1的虚拟方法
getPrice
,在
property
中重写它以返回传递给构造函数的价格。然后,在显示逻辑中,您只需检查价格是否大于0即可显示信息。@p这是一个好主意,但如果我想使用每个子类中的每个方法,我必须这样做,否?是的,另一个解决方案意味着您要检查每个情况的类型,以便正确反应,并且不满足运行时异常:
if(typeid(board[I]).name==“Property”){…}否则如果(typeid(board[i])==“CommunityChest”){…}…
您需要检查实例的类型,以便能够将其转换为子类型以调用基础方法。@p您能给我一个语法示例吗?例如,我知道
board[1]
是一个属性,所以我可以运行
((property*)board[1])->getPrice()
?另一个解决方案是在
GameSquare
类中实现一个返回-1的虚拟方法
getPrice
,在
property
中重写它以返回传递给构造函数的价格。然后,在显示逻辑中,您只需检查价格是否大于0即可显示信息。@p这是一个好主意,但如果我想使用每个子类中的每个方法,我必须这样做,否?是的,另一个解决方案意味着您要检查每个情况的类型,以便正确反应,并且不满足运行时异常:
if(typeid(board[I]).name==“Property”){…}如果(typeid(board[i])==“CommunityChest”){…}…
我喜欢这个解决方案,这就是我在C#或JS中实现它的方式,但是我没有足够的技能在C++中提出一个代码片段。我喜欢这个解决方案,这就是我实现它的方式