如何在 C++ 中从父类对象数组中的子类调用函数

问题描述 投票:0回答:1

我正在尝试用

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++ 还很陌生。

c++ inheritance
1个回答
0
投票

这是我在代码中作为注释编写的示例:

#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(); 
}
© www.soinside.com 2019 - 2024. All rights reserved.