在C++中,继承超类的正确方法是什么,以便它们的子类在超级类和子类中没有重复的属性?



以下代码是我要做的事情的简单示例。目标是在超级类中拥有所有游戏逻辑。然后,在必要时,为平台特定功能添加子类。

#include <iostream>
// Base Game and GameBoard classes to handle all of the core logic
class GameBoard
{
public:
    GameBoard();
    void performMove(int value);
protected:
    int board[4][4];
};
class Game
{
public:
    Game();
    GameBoard gameBoard;
    void performMove(int value);
};
// Derived Game and GameBoard classes to handle the user interaction IO.
class DerivedGameBoard : public GameBoard
{
public:
    DerivedGameBoard();
    void print();
};
class DerivedGame : public Game
{
public:
    DerivedGame();
    DerivedGameBoard gameBoard;
};
Game::Game() {
    gameBoard = GameBoard();
}
void Game::performMove(int value) {
    gameBoard.performMove(value);
}

DerivedGame::DerivedGame() {
    gameBoard = DerivedGameBoard();
}
GameBoard::GameBoard()
{
    for (int i = 0; i < 4; ++i) {
        for (int j = 0; j < 4; ++j) {
            board[i][j] = 0;
        }
    }
}
void GameBoard::performMove(int value)
{
    for (int i = 0; i < 4; ++i) {
        for (int j = 0; j < 4; ++j) {
            board[i][j] = value;
        }
    }
}
DerivedGameBoard::DerivedGameBoard()
{
    for (int i = 0; i < 4; ++i) {
        for (int j = 0; j < 4; ++j) {
            board[i][j] = 1;
        }
    }
}
void DerivedGameBoard::print()
{
    for (int i = 0; i < 4; ++i) {
        for (int j = 0; j < 4; ++j) {
            std::cout << board[i][j];
        }
        std::cout << std::endl;
    }
}

这是我正在测试这些类交互的地方。我假设的或所需的输出在评论中。

int main(int argc, char** argv)
{
    std::cout << "Test Derivation" << std::endl;
    DerivedGame game = DerivedGame();
    game.gameBoard.print(); // Prints all 1s as expected
    game.gameBoard.performMove(2);
    game.gameBoard.print(); // Prints all 2s as expected
    game.performMove(3);
    game.gameBoard.print(); // Prints all 2s, which is unexpected.
}

这种类型的继承是否可以在C 中?在这种情况下,董事会是否需要指针?我想念明显的东西吗?

这是一种方式(大写,因为非常重要)

 class Base
 {
   virtual BaseAttr& getAttr() = 0;
   // methods that use getAttr
 };
 class Derived final : public Base
 {
   // Covariant return type 
   DerivedAttr& getAttr() override {
     return attr;
   }
   // more methods that use getAttr
   DerivedAttr attr;
 };

此设计有时称为"智能儿童设计模式"。

重要的是要注意您的基类是抽象的,并且您的具体类是最终的(不进一步得出)。总是这样做是一种很好的做法。这种设计样式的一种极端形式是仅从纯界面公开得出(又称纯抽象类)。

首先,我想说的话,以避免整个设计。新的C 程序员过度使用的继承,在这里,您拥有一个与VTABLES的类层次结构,实际上不需要一个,这增加了很多不必要的并发症。


无论如何,如果派生的类需要其他gameBoard,则必须通过基类指针(或参考)访问董事

有几种方法可以解决此问题。这是一个可能的骨架:

struct BasicGame
{
    std::unique_ptr<BasicBoard> p_board;
    BasicGame(BasicBoard *new_board): p_board(new_board) {}
    virtual ~BasicGame() = 0;   // make this abstract
};
struct Game1 : BasicGame
{
     Game1(): BasicGame{ new Board1 } {}
};
struct Game2 : BasicGame
{
     Game2(): BasicGame{ new Board2 } {}
};

这样,例如,当您构造Game2时,p_board指向Board2类型的板(当然必须从BasicBoard派生,并且具有虚拟函数);接受BasicBoard参考的功能将能够与p_board一起使用。

最新更新