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

时间:2021-04-18 20:37:58

标签: c++ oop circular-dependency

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

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

导致实体和地图之间的循环依赖。我尝试将实体的行走逻辑移到 Map 类中,但它导致了许多其他问题,在我看来不太正确,因为我想将所有逻辑封装在一个 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
         }
     }
}

2 个答案:

答案 0 :(得分:3)

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

class Entity;

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

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

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

map.cpp #include 是两个头文件,首先,这变成了一个大无汉堡。使用类似的解决方案,同时使用 MapEntity 的方法来解决它们的循环依赖关系。

答案 1 :(得分:2)

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

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

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

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