C++ Derived classes 无法修改基 class' 属性,但外部 class 可以

C++ Derived classes cannot modify a base class' attributes but an external class can

我正在开发一个 Poker Engine,以便不同的 PokerPlayer 代理可以在锦标赛模拟中相互对抗。一旦我的项目完成,我希望人们在 PR 中提交他们自己的代理。为了这样做,他们只需要用他们的 MyPokerPlayer class 派生 PokerPlayer class 并覆盖play() 方法。但我想确保他们的代理人不会作弊。我不希望他们能够改变他们拥有的金钱,也不希望他们能够改变他们在游戏开始时得到的卡牌。

问题是 Game class 在下注时需要能够拿走 PokerPlayer 的钱(或者在他们获胜时给他们底池)并且需要能够在游戏开始时设置 PokerPlayer 的牌。所以 PokerPlayer 派生的 classes 不能直接更新自己的钱和牌,但外部 class Game 可以。

PokerPlayer.h(这是代理推导出来的class)

class PokerPlayer
{
private:
    bool alive = true;
    QList<Card> cards;
    int money;

public:
    PokerPlayer();
    int getMoney() const;
    bool isAlive() const;
    virtual Action* play() = 0;
};

Game.cpp(我给玩家分配他们的牌,接受他们的赌注,等等)

...
void Game::assignCardsToEveryPlayer() {
    foreach (PokerPlayer* player, this->getPlayers()) {
        QSet<Card> cards = PokerGameManager::generateUniqueCards(2);
        player->setCards(cards.toList());
    }
}
...

我不想要的: MYPokerPlayer.cpp(特工)

Action* MYPokerPlayer::play() override {
    this->setMoney(1000000);
    this->setCards(ACE, ACE);
    // you get the idea...
}

我怎样才能做到这一点?

感谢您的宝贵时间,

您可以将金钱和其他不应被欺骗的值存储为您的基地的私有成员 class 并将它们的更改限制为仅 PokerPlayer 的私有函数,这些函数应由游戏或任何假定的调用能够改变的:

class Game;

class PokerPlayer {
  friend class Game;
private:
  int money;
public:
  int getMoney() const;
};

让我们回顾一下 classes 背后的概念。 PokerPlayer是其中一位选手。这个玩家负责跟踪它是否还活着,它有哪些牌,它有多少钱。这听起来像是对不允许作弊的游戏的准确模拟吗?

没有?为什么不?一方面,dealer/house 决定谁得到哪些牌。玩家可以查看卡片但不能更改它们。所以你的 class 应该是相似的。 (钱是一个值得分析的有趣方面,因为真正的玩家可能会带 ATM 卡……;))玩家购买筹码,坐下,然后采取行动。其他一切都由房子控制(或至少监督)。玩家带来的只是起步资金和头脑(即如何play())。

让我们看看是否可以更准确地为扑克游戏建模。 table 周围坐着一群人。 table上有很多卡片,其中一些可以被某些玩家查看。所以...也许在您取消 play 方法后,您所说的 "player" 应该更准确地被视为 "chair" 。 table 拥有椅子,给每个椅子发牌,并处理移动扑克筹码 to/from 椅子(from/to 底池)。

每个玩家都可以缩小到 table 视图(用于下注、弃牌等)、const 椅子视图(用于查看他们的牌和状态) ), 加上虚拟 play 方法。玩家通过从 table 购买筹码加入游戏,然后 table 分配给他们一个 chairplayer只能通过table提供的方法影响游戏。


不可否认,作弊仍然是可能的(例如,从 chair 中丢弃 const)。 C++ 语言与源代码中的安全性无关。存在的护栏是为了防止意外侵权;他们不会阻止从事同一程序的其他人的恶意行为。尽管如此,您仍可以引入一定程度的间接访问,使事情更加安全。给玩家看的 chair 可能是 table 维护的 chair 的副本。恶意程序员操纵他们的椅子副本不会改变 table 曲目。