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
分配给他们一个 chair
。 player
只能通过table
提供的方法影响游戏。
不可否认,作弊仍然是可能的(例如,从 chair
中丢弃 const
)。 C++ 语言与源代码中的安全性无关。存在的护栏是为了防止意外侵权;他们不会阻止从事同一程序的其他人的恶意行为。尽管如此,您仍可以引入一定程度的间接访问,使事情更加安全。给玩家看的 chair
可能是 table
维护的 chair
的副本。恶意程序员操纵他们的椅子副本不会改变 table
曲目。
我正在开发一个 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
分配给他们一个 chair
。 player
只能通过table
提供的方法影响游戏。
不可否认,作弊仍然是可能的(例如,从 chair
中丢弃 const
)。 C++ 语言与源代码中的安全性无关。存在的护栏是为了防止意外侵权;他们不会阻止从事同一程序的其他人的恶意行为。尽管如此,您仍可以引入一定程度的间接访问,使事情更加安全。给玩家看的 chair
可能是 table
维护的 chair
的副本。恶意程序员操纵他们的椅子副本不会改变 table
曲目。