1

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

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

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

我该如何解决这个问题?

4

4 回答 4

3

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

在此处输入图像描述

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

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

在此处输入图像描述

一种方法是在Game需要时将引用传递给它自己的属性Player

例如有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)
   ...
 }

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

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

于 2013-09-21T14:01:20.907 回答
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必须将该方法移至提供 Game 的完整定义的 Player.cpp 文件中。

于 2013-09-21T13:40:42.307 回答
1

需要前向声明 - http://en.wikipedia.org/wiki/Forward_declaration

于 2013-09-21T13:29:27.160 回答
1

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

于 2013-09-21T13:28:40.343 回答