Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/140.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++;相互类依赖 我正在用C++写一个纸牌游戏。我有一个玩家类,它处理动作(即选择一张牌)。如果玩家是人类,它将使用GUI类,如果是计算机,它将使用AI类_C++_Class_Include_Structure - Fatal编程技术网

C++;相互类依赖 我正在用C++写一个纸牌游戏。我有一个玩家类,它处理动作(即选择一张牌)。如果玩家是人类,它将使用GUI类,如果是计算机,它将使用AI类

C++;相互类依赖 我正在用C++写一个纸牌游戏。我有一个玩家类,它处理动作(即选择一张牌)。如果玩家是人类,它将使用GUI类,如果是计算机,它将使用AI类,c++,class,include,structure,C++,Class,Include,Structure,为了让AI类做出决策,它需要了解游戏中每个玩家的一些变化,例如手上的牌数。现在我为AI类中向量中的每个玩家存储一个玩家指针 然而,这导致了我的问题,AI类需要#包括玩家类,而玩家类需要#包括AI类 也许解决方案不是如何处理#includes,而是一种更好的方法来构造类?有时不必为了使用它而包含类的头。例如,如果只使用指向类的指针或引用,则可以向前声明它:而不是 #include "player.h" class AI { std::vector<player *> pl; };

为了让AI类做出决策,它需要了解游戏中每个玩家的一些变化,例如手上的牌数。现在我为AI类中向量中的每个玩家存储一个玩家指针

然而,这导致了我的问题,AI类需要#包括玩家类,而玩家类需要#包括AI类


也许解决方案不是如何处理#includes,而是一种更好的方法来构造类?

有时不必为了使用它而包含类的头。例如,如果只使用指向类的指针或引用,则可以向前声明它:而不是

#include "player.h"
class AI
{
  std::vector<player *> pl;
};
#包括“player.h”
类AI
{
std::向量pl;
};
你可以写

class player;
class AI
{
  std::vector<player *> pl;
};
class播放器;
类AI
{
std::向量pl;
};

我猜玩家和AI类都有用于该纸牌游戏的通用方法(获取纸牌、放置纸牌、洗牌、下注、全包…),这些方法可以从基类CardPlayer继承,也可以在运行时使用接口组合(请参阅)

要将Human Player类连接到GUI,请创建合适的接口,例如:

typedef struct PlayerInfoStruct {
    ---player info variables here---
};

class IGUIPlayer {
    virtual PlayerInfoStruct GetPlayerInfo(...) = 0;
    ---other methods exclusive to the GUI-player interaction here---
};
并在继承该接口的HumanPlayer中实现该接口:

class HumanPlayer : public CardPlayer, public IGUIPlayer {
    PlayerInfoStruct GetPlayerInfo() {---method---}
    ---other methods here---
}
在GUI中,您可以使用界面指向每个人类玩家:

---somewhere in your GUI Class---
IGUIPlayer* humanplayer1 = <pointer to HumanPlayer>;
——GUI类中的某个地方---
IGUIPlayer*humanplayer1=;
这样,GUI类就依赖于IGUIPlayer。HumanPlayer同时依赖于IGUIPlayer和CardPlayer。AIPlayer仅依赖于CardPlayer。没有循环的东西


使用界面意味着您可以随时在GUI中提供AI玩家的信息,只需将IGUIPlayer继承给AIPlayer并实现纯虚拟方法,而无需对GUI进行任何修改。我花了一点时间才习惯(我还在继续学习),但我无法抗拒它内在的力量

请注意,您通常可以使用前向声明,例如
classplayer而不是包含整个定义,以避免循环标头依赖关系。但听起来你最好还是用一个单独的“游戏的可见状态”对象。我想你可能想错了。你有一个“付款人”界面,它有“牌数”和“扑克牌”之类的东西。一个玩家可以是“人类玩家”或“AI玩家”。你还没有为你的后一个断言提出必要的理由;玩家类需要了解AI类。例如:当玩家是AI时,该玩家的UI活动应该被赋予属性并无效,但AI做出了该调用和相应的规定;不是球员。无论是通过派生还是特征设计,两者都会起作用。@MikeSeymour可见状态实际上是一个很好的主意,我会尝试,它对我来说也很简单,这很好:)这实际上是我第一次尝试的,但是Xcode说成员访问不完整类型的“Player”您是否在cpp文件中编写了所有使用该向量的函数,并且是否在其中包含了
“Player.h”
?如果它仍然不起作用,您可以将vector替换为指向vector的指针,或者“unique”ptr。