【问题标题】:How can two Classes in C++ notice each other? [duplicate]C++ 中的两个类如何相互通知? [复制]
【发布时间】:2013-09-26 19:23:01
【问题描述】:

例如一个包含三个类 Player、Bot 和 Game 的小电脑游戏

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

// 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 列表

//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 的问题,反之亦然。

我该如何解决这个问题?

【问题讨论】:

  • 为什么 player.h 包含 game.h?在您发布的代码中没有理由。如果 player.h 有充分的理由包含 game.h,那么我们需要知道它是什么,然后才能给出解决方案。
  • 约翰,你是对的,谢谢。我已经纠正了。 for 循环应该在玩家类中,而不是在游戏中。

标签: c++


【解决方案1】:

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

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

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

一种方法是让GamePlayer 需要它们时传递对其自身属性的引用。

例如让collision 采用bots 参数而不是`Game

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)
   ...
 }

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

如果一切都失败了,您可以返回使用前向声明。

【讨论】:

  • 太好了,感谢您的帮助和图表!它有效:)
【解决方案2】:

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

像这样

播放器.h

#include "Bot.h"

class Game; // forward declaration

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

播放器.cpp

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

bool Player::collision(Game g)  {

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

前向声明告诉编译器Game 是一个类的名称,仅此而已。因此必须将Player::collision 方法移动到提供完整游戏定义的 Player.cpp 文件中。

【讨论】:

    【解决方案3】:

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

    【讨论】:

      【解决方案4】:

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-09-11
        • 2012-03-25
        • 1970-01-01
        • 2012-11-02
        • 2011-06-25
        相关资源
        最近更新 更多