以下代码是我要做的事情的简单示例。目标是在超级类中拥有所有游戏逻辑。然后,在必要时,为平台特定功能添加子类。
#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
一起使用。