C++ c++;OOP设计-将数据成员传递给其他类-合理吗?

C++ c++;OOP设计-将数据成员传递给其他类-合理吗?,c++,C++,我还有一个问题,希望能总结一下我的想法 假设我有以下3个类: 职业玩家: class Player { private: int positionX, positionY; public: void move(Board& b) { // player changes its position on the board(move) b.removeCharFromBoard(positionX, positionY); position

我还有一个问题,希望能总结一下我的想法

假设我有以下3个类:

职业玩家:

class Player {
private:
    int positionX, positionY;
public:
    void move(Board& b) {
      // player changes its position on the board(move)
      b.removeCharFromBoard(positionX, positionY);
      positionX++;
      positionY++;
      // 'P' indicates a Player in the Board....
      b.insertCharToBoard(positionX, positionY, 'P');
    }
};
class Board {
private:
    // BOARD_C and BOARD_R are both "#define ..." for some integer number.
    char board[BOARD_C][BOARD_R];
};
class GameEngine {
private:
     Board* board;
public:
     void playTurn(const Player& p) {
        p.move(board);
     }
};
班级董事会:

class Player {
private:
    int positionX, positionY;
public:
    void move(Board& b) {
      // player changes its position on the board(move)
      b.removeCharFromBoard(positionX, positionY);
      positionX++;
      positionY++;
      // 'P' indicates a Player in the Board....
      b.insertCharToBoard(positionX, positionY, 'P');
    }
};
class Board {
private:
    // BOARD_C and BOARD_R are both "#define ..." for some integer number.
    char board[BOARD_C][BOARD_R];
};
class GameEngine {
private:
     Board* board;
public:
     void playTurn(const Player& p) {
        p.move(board);
     }
};
类游戏引擎:

class Player {
private:
    int positionX, positionY;
public:
    void move(Board& b) {
      // player changes its position on the board(move)
      b.removeCharFromBoard(positionX, positionY);
      positionX++;
      positionY++;
      // 'P' indicates a Player in the Board....
      b.insertCharToBoard(positionX, positionY, 'P');
    }
};
class Board {
private:
    // BOARD_C and BOARD_R are both "#define ..." for some integer number.
    char board[BOARD_C][BOARD_R];
};
class GameEngine {
private:
     Board* board;
public:
     void playTurn(const Player& p) {
        p.move(board);
     }
};
您认为GameBoard的playTurn函数调用玩家的move函数时使用参数“board”合理吗? 我需要这样做,以便在董事会数据成员中标记球员已经改变了位置。 它是否保持OOP的基本规则

谢谢大家,,
辛迪加

你的方法很好。GameEngine将用作游戏的某种控制器。多亏了它,你可以过滤玩家的动作,检查这种动作是否可行,或者在特定玩家操作的情况下做其他事情


第二,对于这个解决方案,您不必将玩家连接到特定的棋盘,这就扩展了其他选项的可能性,比如在棋盘之间轻松转移玩家。我认为您已经走上了一条好路:)

您必须考虑您的应用程序将如何更改,以及您希望引入哪些功能。从这段代码来看,它看起来还可以,但当您引入新功能时,它会是这样吗


另一个解决方案是将其放入仅玩家移动逻辑,它将更新其位置,然后您的游戏引擎将根据所有玩家当前位置更新棋盘条目。想象一下,在一段时间内,你会想实施碰撞检测,然后在每个玩家更新其位置或动作后,碰撞检测就会发生并纠正这些动作,只有稍后在你的棋盘上才会正确更新。

是的,在这种情况下,这似乎是合理的(通过“在这种情况下”我的意思是“考虑到我对
GameEngine
Board
类的语义以及它们的关联/聚合关系的性质的猜测”):

  • GameEngine
    中使用智能指针而不是原始指针来固定
    对象
    unique_ptr
    可能是您在本例中想要的,因为所有其他别名似乎只是观察者,并且board对象的生存期绑定到
    GameEngine
    对象之一。但是,如果需要共享所有权,请选择
    shared\u ptr
    。尽量不要使用原始指针、
    new
    delete
    ,因为它们会导致错误代码
  • 您仍然需要在
    Board
    类的界面上提供公共函数来修改Board,因为
    Player
    将无法访问其私有成员变量(而
    Board
    恰好是一个)
  • 不要使用
    #定义
    s,而是使用
    constepr
    值来确定电路板的大小(如果您使用的是C++11)。您可能还需要考虑创建安全的二维C样式数组。

  • 很多事情已经说过了,但请允许我补充一点

    (无论是否为
    私有
    )传递给
    播放器
    本身并不坏,这种设计在几种体系结构中使用(代码取自SFML 2.0):

    RenderTarget
    是您的
    。这里需要了解的是,您将仅使用
    板的公共界面(您可以访问该界面)在
    板上操作。在上面的代码中,
    draw()
    是在
    target
    上使用的方法,用于强制它绘制某物

    将内部对象传递给更高级别的类(如
    Player
    )的整个想法可以解释为,其中可以有几个接口
    Board
    的实现,几个类可以实现
    IBoardManipulator
    (或类似的东西)

    也就是说,我认为最好遵循游戏引擎的总体思路,即:

  • 注册游戏实体(在本例中为玩家)
  • 捕获播放器的输入
  • 对玩家输入进行消化和反应(请求移动玩家)
  • 处理游戏逻辑(检查玩家是否可以移动到给定位置,如果可以-移动他)
  • 对于每个注册实体,
    GameEngine
    将调用
    draw()
    传递
    Board
    作为实体可以使用的目标
  • 重复步骤2

  • 我并不是说对于一个简单的体系结构来说这是必要的,但从长远来看,它比处理每个类似
    播放器
    的类可以对
    棋盘

    移动()
    返回玩家移动量并且棋盘简单地更新它的讨厌事情要容易得多。。。?由你决定是的,但这只是一个简单的例子。随着游戏变得越来越复杂,解释每个玩家动作的需求变得令人沮丧。我只是觉得它不能与OOP规则和平共处,因为玩家类不应该知道/熟悉Board类/对象。我说的对吗?在我看来,玩家真的不需要知道任何关于棋盘的事情,它应该只考虑自己。我想这会使你的设计脱钩,使它更具凝聚力。非常感谢你的回答。我将添加一个箭头、碰撞(仅在玩家之间)和支持2-3个玩家(人类和计算机)。我只是一直认为,真正禁止让一个像玩家这样的职业知道它的棋盘。这是我可以用来推断很多其他项目的一点,在这些项目中,为了OOP规则,我试图避免传递数据成员的ref或this。@syndicatorbb:这就是我害怕的:-)不要“推断太多”。一个类不应该知道另一个类的实现细节这一事实是一个有效的原则,它被称为信息隐藏。你不会想放弃的。然而,在这里,我觉得board是
    GameEngine
    类的一个可见元素。p