【问题标题】:How can I avoid circular dependencies between Entities and Map?如何避免实体和地图之间的循环依赖?
【发布时间】:2021-04-18 20:37:58
【问题描述】:

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

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

【问题讨论】:

    标签: c++ oop circular-dependency


    【解决方案1】:

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

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

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

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

    map.cpp#includes 两个头文件,首先,这变成了一个很大的空包。使用Map's 和Entity's 方法的类似解决方案来解决它们的循环依赖关系。

    【讨论】:

      【解决方案2】:

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

      指针/引用可以与实体/映射的前向声明一起使用,但是当您使用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()                    
          //...
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2022-01-11
        • 1970-01-01
        • 2021-04-23
        • 1970-01-01
        • 2011-03-12
        • 2013-02-06
        • 1970-01-01
        • 2012-02-15
        相关资源
        最近更新 更多