我一直在编写一个简单的棋盘游戏,以在实践中学习 C++ 的概念。我已经实现了板:它由图 block 组成,每个图 block 都是从父类继承的子类。棋盘是一个具有图 block vector 的类。
瓷砖有几种。其中一些可以由玩家购买。有几种不同类型的可购买瓷砖以及不同的属性,所以我认为为可以购买的瓷砖制作基类 TileOnSale 并制作实际类型的子类很可爱,我在下面的代码中提供了其中两个.
现在我的问题是如何访问未在父类 (TileOnSale) 中定义的子成员函数? Board 使用各种不同的图 block 进行初始化,因此我可以使用 getTile(int location) 函数从那里提取一个图 block 。但是,这会被解释为只是一个 Tile,而不是 TileOnSale 或 StreetTile。我知道没有办法以这种方式掌握 StreetTile 的 buildHouses 函数。
那么,是否有一种健壮的,甚至更好的,巧妙的方法来做到这一点?我可以制作一个模板或其他东西来保存可能是 StreetTiles 或 StationTiles 或其他 Tile 的 Tile 对象吗? 还是我应该重新设计类结构?
这是一个简单的代码。我试图只提供理解问题所需的内容。此外,最初 Tile 和 Board 在它们自己的头文件中。我决定没有必要显示具有自有 TileOnSale 对象 vector 但保留与 Board 完全相同的访问问题的 Player 类。
// Board.h
#include "Tile.h"
typedef vector<Tile> Tiles;
class Board
{
public:
Board();
~Board();
Tile getTile(int location);
private:
Tiles tiles;
};
// Tile.h
class Tile
{
public:
Tile();
~Tile();
protected:
tileType tile_type; // this is enum containing unique type
string description;
};
class TileOnSale : public Tile
{
public:
TileOnSale();
~TileOnSale();
virtual int getRent() const { return 0; };
};
class StreetTile : public TileOnSale
{
public:
StreetTile();
~StreetTile();
int getRent() override;
void buildHouses(int number);
private:
int houses;
};
class StationTile : public TileOnSale
{
public:
StationTile();
~StationTile();
int getRent() override;
};
编辑:向代码添加了一个可能澄清的注释。
最佳答案
您可能想看一下 visitor pattern .
In essence, the visitor allows one to add new virtual functions to a family of classes without modifying the classes themselves; instead, one creates a visitor class that implements all of the appropriate specializations of the virtual function. The visitor takes the instance reference as input, and implements the goal through double dispatch.
双重分派(dispatch)意味着您实际上调用了一个虚函数两次:第一次调用主题,然后多态调用访问者。
在您的情况下,只有一种方法,即 build 房屋,但您可能希望稍后添加其他方法(例如在屏幕上绘制它们)。鉴于您当前的示例,您应该将此方法添加到 Tile 和 StreetTile:
virtual void accept(Visitor& v) { v.visit(*this); }
这是访问者基类的实现:
class Visitor {
public:
virtual void accept(Tile& t) = 0;
virtual void accept(StreetTile& t) = 0;
};
之后你可以实现一个Builder类:
class Builder: public Visitor {
private:
int numberOfHouses;
public:
Builder(int n): numberOfHouses(n) {}
virtual void accept(Tile& t) {}
virtual void accept(StreetTile& t) {
t.buildHouses(numberOfHouses);
}
};
在那之后,您所要做的就是构建这样一个构建器,并在您的瓦片 vector 中的每个瓦片上调用它:
Builder b(10);
for (Tile tile : tiles) {
tile.accept(b);
}
关于c++ - 在父类中访问子类的功能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20354164/
类classAprivatedeffooputs:fooendpublicdefbarputs:barendprivatedefzimputs:zimendprotecteddefdibputs:dibendendA的实例a=A.new测试a.foorescueputs:faila.barrescueputs:faila.zimrescueputs:faila.dibrescueputs:faila.gazrescueputs:fail测试输出failbarfailfailfail.发送测试[:foo,:bar,:zim,:dib,:gaz].each{|m|a.send(m)resc
我有一个模型:classItem项目有一个属性“商店”基于存储的值,我希望Item对象对特定方法具有不同的行为。Rails中是否有针对此的通用设计模式?如果方法中没有大的if-else语句,这是如何干净利落地完成的? 最佳答案 通常通过Single-TableInheritance. 关于ruby-on-rails-Rails-子类化模型的设计模式是什么?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.co
我有一个包含模块的模型。我想在模块中覆盖模型的访问器方法。例如:classBlah这显然行不通。有什么想法可以实现吗? 最佳答案 您的代码看起来是正确的。我们正在毫无困难地使用这个确切的模式。如果我没记错的话,Rails使用#method_missing作为属性setter,因此您的模块将优先,阻止ActiveRecord的setter。如果您正在使用ActiveSupport::Concern(参见thisblogpost),那么您的实例方法需要进入一个特殊的模块:classBlah
我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server
我正在使用Sequel构建一个愿望list系统。我有一个wishlists和itemstable和一个items_wishlists连接表(该名称是续集选择的名称)。items_wishlists表还有一个用于facebookid的额外列(因此我可以存储opengraph操作),这是一个NOTNULL列。我还有Wishlist和Item具有续集many_to_many关联的模型已建立。Wishlist类也有:selectmany_to_many关联的选项设置为select:[:items.*,:items_wishlists__facebook_action_id].有没有一种方法可以
下面例子中的Nested和Child有什么区别?是否只是同一事物的不同语法?classParentclassNested...endendclassChild 最佳答案 不,它们是不同的。嵌套:Computer之外的“Processor”类只能作为Computer::Processor访问。嵌套为内部类(namespace)提供上下文。对于ruby解释器Computer和Computer::Processor只是两个独立的类。classComputerclassProcessor#Tocreateanobjectforthisc
只是想确保我理解了事情。据我目前收集到的信息,Cucumber只是一个“包装器”,或者是一种通过将事物分类为功能和步骤来组织测试的好方法,其中实际的单元测试处于步骤阶段。它允许您根据事物的工作方式组织您的测试。对吗? 最佳答案 有点。它是一种组织测试的方式,但不仅如此。它的行为就像最初的Rails集成测试一样,但更易于使用。这里最大的好处是您的session在整个Scenario中保持透明。关于Cucumber的另一件事是您(应该)从使用您的代码的浏览器或客户端的角度进行测试。如果您愿意,您可以使用步骤来构建对象和设置状态,但通常您
如何将send与+=一起使用?a=20;a.send"+=",10undefinedmethod`+='for20:Fixnuma=20;a+=10=>30 最佳答案 恐怕你不能。+=不是方法,而是语法糖。参见http://www.ruby-doc.org/docs/ProgrammingRuby/html/tut_expressions.html它说Incommonwithmanyotherlanguages,Rubyhasasyntacticshortcut:a=a+2maybewrittenasa+=2.你能做的最好的事情是:
我对如何计算通过{%assignvar=0%}赋值的变量加一完全感到困惑。这应该是最简单的任务。到目前为止,这是我尝试过的:{%assignamount=0%}{%forvariantinproduct.variants%}{%assignamount=amount+1%}{%endfor%}Amount:{{amount}}结果总是0。也许我忽略了一些明显的东西。也许有更好的方法。我想要存档的只是获取运行的迭代次数。 最佳答案 因为{{incrementamount}}将输出您的变量值并且不会影响{%assign%}定义的变量,我
我想从then子句中访问case语句表达式,即food="cheese"casefoodwhen"dip"then"carrotsticks"when"cheese"then"#{expr}crackers"else"mayo"end在这种情况下,expr是食物的当前值(value)。在这种情况下,我知道,我可以简单地访问变量food,但是在某些情况下,该值可能无法再访问(array.shift等)。除了将expr移出到局部变量然后访问它之外,是否有直接访问caseexpr值的方法?罗亚附注我知道这个具体示例很简单,只是一个示例场景。 最佳答案