gpt4 book ai didi

c++ - 在父类中访问子类的功能

转载 作者:塔克拉玛干 更新时间:2023-11-03 02:02:57 29 4
gpt4 key购买 nike

我一直在编写一个简单的棋盘游戏,以在实践中学习 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/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com