前瞻性声明&循环依赖

时间:2013-05-28 22:24:18

标签: c++ dependencies declaration circular-dependency forward

我有两个课程,实体和水平。两者都需要访问彼此的方法。因此,使用#include会产生循环依赖的问题。因此,为了避免这种情况,我尝试在Entity.h中转发声明Level:

class Level { };

但是,由于Entity需要访问Level中的方法,因此它无法访问此类方法,因为它不知道它们存在。有没有办法解决这个问题,而无需重新声明实体中的大部分级别?

2 个答案:

答案 0 :(得分:8)

正确的前瞻性声明只是:

class Level;

注意缺少花括号。这告诉编译器有一个名为Level的类,但没有关于它的内容。然后,您可以自由地将指针(Level *)和引用(Level &)用于此未定义的类。

请注意,您无法直接实例化Level,因为编译器需要知道类的大小才能创建变量。

class Level;

class Entity
{
    Level &level;  // legal
    Level level;   // illegal
};

为了能够在Level的方法中使用Entity,理想情况下,您应该在单独的Level定义 .cpp的方法文件,只有在标题中声明它们。将声明与定义分开是C ++的最佳实践。

// entity.h

class Level;

class Entity
{
    void changeLevel(Level &);
};


// entity.cpp

#include "level.h"
#include "entity.h"

void Entity::changeLevel(Level &level)
{
    level.loadEntity(*this);
}

答案 1 :(得分:1)

你有两个选择:

  1. 使用指针,在这种情况下,你的前向声明应该没问题。
  2. 内联一个类的方法,在这种情况下,如果包含.h文件,则可以使用另一个类的方法。
  3. 就我个人而言,我会沿着1号路径前进,它更干净,可以更方便地访问。我使用了很多shared_ptr,所以我不必担心删除...

    Entity.h:
    class Level;
    class Entity {
    
    private:
       Level* m_pLevel;
    
    public:
       bool  CheckLevel ();
       bool WasItThere();
    
    
    Level.h
    
    class Entity;
    class Level {
    
    private:
       Entity* m_pEntity;
    
    
    
        public:
           public bool CheckMyStuff();
           public bool CheckItOut() { return m_pEntity->WasItThere();}
    }
    
    
    Entity.cpp
    
    #include "Level.h"
    
    bool Entity::CheckLevel () {
      return true;
    }
    
    
    bool Entity::CheckLevel() {
       return m_pLevel->CheckMyStuff();
    }
    
    bool Entity::WasItThere() {
       return true;
    }
    
    
    
    Level.cpp
    
    bool Level::CheckMyStuff() { 
        return true;
    }
    
    bool Level::CheckItOut() { 
        return m_pEntity->WasItThere();
    }