循环依赖/不完整类型

时间:2011-10-05 19:31:49

标签: c++ circular-dependency incomplete-type

在C ++中,我遇到循环依赖/不完整类型的问题。情况如下:

Stuffcollection.h

#include "Spritesheet.h";
class Stuffcollection {
    public:
    void myfunc (Spritesheet *spritesheet);
    void myfuncTwo ();
};

Stuffcollection.cpp

void Stuffcollection::myfunc(Spritesheet *spritesheet) {
    unsigned int myvar = 5 * spritesheet->spritevar;
}
void myfunc2() {
    //
}

Spritesheet.h

#include "Stuffcollection.h"
class Spritesheet {
    public:
    void init();
};

Spritesheet.cpp

void Spritesheet::init() {
    Stuffcollection stuffme;
    myvar = stuffme.myfuncTwo();
}
  • 如果我保留如上所示的包含,我会收到编译错误 Stuffcollection.h中的spritesheet has not been declared(第4行) 以上)。我理解这是由于循环依赖。
  • 现在,如果我将#include "Spritesheet.h"更改为转发 在Stuffcollection.h中声明class Spritesheet;,我得到了 编译错误invalid use of incomplete type 'struct Spritesheet' 在Stuffcollection.cpp中(上面的第2行)。
  • 同样,如果我在Spritesheet.h中将#include "Stuffcollection.h"更改为class Stuffcollection;,我会收到编译错误aggregate 'Stuffcollection stuffme' has incomplete type and cannot be defined 在Spritesheet.cpp中(上面的第2行)。

我该怎么做才能解决这个问题?

3 个答案:

答案 0 :(得分:4)

您应该在Spritesheet.h中加入Stuffcollection.cpp 只需在头文件中使用forward声明而不是cpp文件,这解决了头文件的循环依赖性。源文件实际上没有循环依赖。

Stuffcollection.cpp需要知道类Spritesheet的完整布局(因为您取消引用它),因此您需要在该文件中包含定义类Spritesheet的标头。

从之前的Q here 开始,我认为类Stuffcollection用于Spritesheet头文件的类声明,因此也就是上面提出的解决方案。

答案 1 :(得分:2)

Spritesheet.h不需要包含Stuffcollection.h,因为在Stuffcollection的类声明中没有使用Spritesheet。将包含行的行移至Spritesheet.cpp,您应该没问题。

答案 2 :(得分:2)

将此表单用于嵌套包含:

Stuffcollection.h

#ifndef STUFFCOLLECTION_H_GUARD
#define STUFFCOLLECTION_H_GUARD
class Spritesheet;
class Stuffcollection {
  public:
  void myfunc (Spritesheet *spritesheet);
  void myfuncTwo ();
};
#endif

Stuffcollection.cpp

#include "Stuffcollection.h"
#include "Spritesheet.h"

void Stuffcollection::myfunc(Spritesheet *spritesheet) {
  unsigned int myvar = 5 * spritesheet->spritevar;
}

void Stuffcollection::myfuncTwo() {
  //
}

Spritesheet.h

#ifndef SPRITESHEET_H_GUARD
#define SPRITESHEET_H_GUARD
class Spritesheet {
  public:
  void init();
};
#endif

Spritesheet.cpp

#include "Stuffcollection.h"
#include "Spritesheet.h"

void Spritesheet::init() {
  Stuffcollection stuffme;
  myvar = stuffme.myfuncTwo();
}

我遵循的一般规则:

  • 不包括来自包含的内容,伙计。如果可能,更喜欢前瞻性声明。
    • 例外:包含系统包含您想要的任何地方
  • 让CPP包含所需的一切,而不是依赖H递归包含它的文件。
  • 始终使用包含警卫。
  • 绝不使用pragma