我有一个名为EntityManager的类,该类在Entity中拥有vector。问题是,Entity在模板函数中使用对EntityManager的引用。这是演示我的意思的代码:

//EntityManager.h
#include "Entity.h"
class EntityManager{
    std::vector<Entity> ents;
public:
    template<class T>
    void someFunc(const Entity & e){
        ...
    }
};

//Entity.h
#include "EntityManager.h"
class Entity{
    EntityManager * mgr;
public:
    template<class T>
    void someOtherFunc(){
        mgr->someFunc<T>(*this);
    }
}


注意,我试图将函数移出声明,如下所示:

//Entity.h
class EntityManager;

class Entity{
    EntityManager & mgr;
public:
    template<class T>
    void someOtherFunc();
}

#include "EntityManager.h"
template<class T>
void Entity::someOtherFunc(){
    mgr->someFunc<T>(*this);
}


如何解决这种依赖性?注意,我不能使用C ++ 11,以防万一解决方案隐藏在这里。

最佳答案

看起来您的依赖项如下所示:


EntityManager包含vectorEntity个。 EntityManager的类定义需要Entity的类定义才能被很好地定义。
Entity包含对EntityManager的引用。它的类定义只需要EntityManager的类型声明即可定义。
EntityManager::someFunc<T>的实现需要EntityManagerEntity的类定义。
Entity::someOtherFunc<T>的实现还需要EntityManagerEntity的类定义。


因此,解决方案将是:


Entity之前包括EntityManager的类定义
EntityManager的类定义之前转发声明Entity
EntityManager的类定义之前不包括Entity的类定义
但要记住在实现EntityManager之前包括Entity::someOtherFunc<T>的类定义,在实现Entity之前包括EntityManager::someFunc<T>的类定义


这应该打破周期。关键的见解是,尽管通常可以内联编写成员函数模板,但是在这种情况下,您必须将它们与类定义分开。如果您声明性地表示依赖关系并使用适当的#include防护,则定义将自动以正确的顺序包括在内。

例如,

实体管理器

EntityManager的类定义需要Entity的类定义。标头需要包含EntityManager的模板化成员函数的实现。

#ifndef ENTITYMANAGER_H
#define ENTITYMANAGER_H
#include "Entity.h"

class EntityManager {
  std::vector<Entity> ents;
public:
  template <typename T>
  inline void someFunc(const Entity &e);
};

#include "EntityManager.cpp.tmpl"

#endif


EntityManager.cpp.tmpl

EntityManager的实现需要Entity的类定义。

#include "Entity.h"

template <typename T>
void EntityManager::someFunc(const Entity &e) {
  // do things with this, e, and T
}


实体

Entity的类定义仅需要EntityManager类型的声明。标头需要包含Entity的模板化成员函数的实现。

#ifndef ENTITY_H
#define ENTITY_H
class EntityManager;

class Entity {
  EntityManager &mgr;
public:
  template <typename T>
  inline void someOtherFunc();
};

#include "Entity.cpp.tmpl"

#endif


Entity.cpp.tmpl

Entity的实现需要EntityManager的类定义。

#include "EntityManager.h"

template <typename T>
void Entity::someOtherFunc() {
  mgr.someFunc<T>(*this);
}

关于c++ - 如何解决具有has-a关系的模板化循环依赖关系?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/31529129/

10-16 04:31