如何避免实体和地图之间的循环依赖?

How can I avoid circular dependencies between Entities and Map?

假设有两个 classes:MapEntity。 Map 有一个指向游戏中所有实体的指针数组,实体使用地图来检查他要去的地方是否有空位。因此,在主要功能中,我正在执行以下操作:

map->getEntity(x, y)->walk(map)

这导致了实体和地图之间的循环依赖。我尝试将实体的行走逻辑移动到 Map class,但它导致了许多其他问题,而且我认为这不太正确,因为我想将所有逻辑封装在一个 entity.walk 中() 方法(检查实体是否可以访问目标字段,是否为空等),所以我不需要在移动实体之前在我的主要功能中检查所有这些。我也尝试过使用前向声明,但在这种情况下它无济于事,因为地图和实体都在使用彼此的方法,这些方法尚未声明。这是我现在拥有的:

class Entity;
class Map {
public:
    void add(Entity* ent) {
        ent->getX()                       //Map.h
        //...
    }
}
#include "Map.h"
class Entity {
     void walk(Map* map) {
         if(map->isEmpty(x, y)) {
             //...                        //Entity.h
         }
     }
}

答案是:将方法定义和实现分离到单独的文件中。

pointer/reference 可以与 Entity/Map 的前向声明一起使用,但是当您使用 map->isEmptyent->getX 时,需要知道整个 class已经定义了。

在您的简短示例中,这应该足够了

class Entity;
class Map {
public:
    void add(Entity* ent);
    bool isEmpty(size_t x, size_t y) { return ...; } // whatever is it
}

class Entity {
     void walk(Map* map) {
         if(map->isEmpty(x, y)) {
             //...                 
         }
     }
     size_t getX() { return ...; } // whatever
}

void Map::add(Entity* ent) {
    ent->getX()                    
    //...
}

只是在header文件中有一个方法声明,仅此而已。简单地不要定义内联方法:

class Entity;

class Map {
public:
    void add(Entity* ent);
}

然后在您的 map.cpp 文件中包含两个 header,并定义方法:

void Map::add(Entity* ent) {
    ent->getX()
}

map.cpp #includes 两个 headers 文件,首先,这变成了一个大 nothing-burger。使用类似的解决方案,同时使用 MapEntity 的方法来解决它们的循环依赖关系。