我正在尝试用
Tile
对象的二维数组制作一个游戏板,这是我制作的一个类。它看起来像这样:
class Board {
private:
Tile m_board[9][9]
public:
Board();
//Constructors, functions, etc
};
class Tile {
private:
char m_type;
//other class members, etc
public:
Tile();
char getType();
void activate(); //This does nothing.
};
class BreakTile: public Tile {
public:
BreakTile();
void activate(); //This does something.
我想要发生的是,我可以转到板上的任何
Tile
,检查它是否是BreakTile
,如果是,则激活它。我在 Board
类中有一个函数,看起来像这样:
void Board::activate(int y, int x)
{
if (m_board[y][x].getType() == 'B')
{
m_board[y][x].activate();
}
}
这可以激活
BreakTile
。然而,它所做的只是从 activate()
类调用 Tile
函数 - 大概是因为这是一个 Tile
数组 - 尽管事实上在 Board
的构造函数中我将一些图块定义为 BreakTile
所以我知道我在这里看到的图块是BreakTile
。我只是不知道如何让计算机识别它。
我一直在尝试看看是否可以将
Tile
转换为 BreakTile
,但我不知道如何开始这样做。我对 C++ 还很陌生。
这是我在代码中作为注释编写的示例:
#include <array>
#include <memory>
#include <iostream>
// First define an abstract base class (or "interface")
class TileItf
{
public:
virtual ~TileItf() = default;
virtual void activate() = 0;
};
// then create overloads for any kind of tile you can have
class EmptyTile : public TileItf
{
void activate() override { std::cout << "."; }
};
class OTile : public TileItf
{
void activate() override { std::cout << "O"; }
};
class XTile : public TileItf
{
void activate() override { std::cout << "X"; }
};
// The board now will contain a 2D array of interfaces to tiles.
// in C++ we don't use new/delete by default anymore, but use containers or smart pointers
class Board
{
public:
Board()
{
// intitialize the board with empty tiles
for (auto& row : m_tiles)
{
for (auto& tile : row)
{
tile = std::make_unique<EmptyTile>();
}
}
// this next line looks simple but it does a few things
// it will destroy the tile at the current position and assign a new tile to it.
m_tiles[0][1] = std::make_unique<OTile>();
m_tiles[1][1] = std::make_unique<XTile>();
}
void activate()
{
// range based for loops (cannot go out of scope)
for (const auto& row : m_tiles)
{
for (const auto& tile : row)
{
tile->activate(); // <== here the derived activate function will be called depending on the concrete tile type
}
std::cout << "\n";
}
}
private:
// Because tiles are polymorphic we need pointers to them (or you get the object slicing that was talked about before)
std::array<std::array<std::unique_ptr<TileItf>, 3>, 3> m_tiles;
};
int main()
{
Board board;
board.activate();
}