C ++中的两个类如何相互通知?

时间:2013-09-21 13:24:39

标签: c++

例如一个带有三个类玩家,机器人和游戏的小型计算机游戏

玩家有一个方法可以检查玩家是否与机器人发生碰撞

// Player.h
#include Game.h   
#include Bot.h

class Player {
    private:
    bool collision(Game g)  {

       for (Bot bot: g.bots)
       ...
     }

};

Bot.h(保持简单,因为它有一些其他属性,如实际位置和目前为止)

// Bot.h


class Bot {
    public:
    Bot()
};

Gameclass处理Gameloop和Bot of Bots

//Game.h
#include Bot.h    
#include Player.h

class Game {

public:
Player player:
std::vector<Bot> bots
void loop() { player.collision() }

};

所以这里我们遇到的问题是Game.h包含Player.h,反之亦然。

我该如何解决这个问题?

4 个答案:

答案 0 :(得分:3)

虽然这里的其他答案肯定在技术上是正确的,但每当我遇到这样的情况时,我都会将其视为指出我设计中存在的潜在缺陷。你所拥有的是循环依赖,如下所示:

enter image description here

这不仅仅是您实现的问题,它意味着类之间存在太多coupling,或者相反,信息隐藏太少。这意味着您无法独立于Player设计Game,例如。

因此,如果可能的话,我更喜欢这样的情况,其中Game作为控制器委托给其他类。

enter image description here

执行此操作的一种方法是GamePlayer需要时将collision传递给自己的属性。

例如,让bots采用bool collision(const std::vector<Bot&> bots) { // note pass objects by const ref is usu preferred in C++ to pass by value for (Bot bot: g.bots) ... } 参数而不是“游戏

{{1}}

(注意,在更复杂的方法中,它可以将接口,即抽象基类传递给自身)。

如果一切都失败了,你可以回去使用前瞻性声明。

答案 1 :(得分:2)

在这种情况下,最简单的方法是转发声明,并将一些代码从头文件移动到源文件。

喜欢这个

Player.h

#include "Bot.h"

class Game; // forward declaration

class Player {
    private:
    bool collision(Game g);
};

Player.cpp

#include "Player.h"
#include "Game.h"

bool Player::collision(Game g)  {

   for (Bot bot: g.bots)
   ...
}

前向声明告诉编译器Game是类的名称,但没有别的。因此必须将Player::collision方法移动到Player.cpp文件中,其中可以使用Game的完整定义。

答案 2 :(得分:1)

我认为你不能这样做,因为如果A包含B,而B包含A,它将是无限大小。事实上,您可以使用前向声明创建两个存储指针的类,以便两个类知道彼此的存在

答案 3 :(得分:1)