循环依赖项/不完整类型

Circular Dependencies / Incomplete Types

本文关键字:类型 依赖 循环      更新时间:2023-10-16

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

物料收集.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();
}
  • 如果我保留如上所示的includes,我会得到编译器错误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行(

我能做些什么来解决这个问题?

您应该在Stuffcollection.cpp中包含Spritesheet.h
只需在头文件中使用正向声明,而不是在cpp文件中使用,即可解决头文件的循环依赖关系。源文件实际上没有循环依赖关系。

Stuffcollection.cpp需要知道类Spritesheet的完整布局(因为你取消了对它的引用(,所以你需要在该文件中包括定义类Spritesheet的头。

根据您之前的Q此处,我认为Stuffcollection类用于Spritesheet头文件的类声明,因此使用了上述提出的解决方案。

将此表单用于嵌套包含:

物料收集.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() {
  //
}

精灵表.h

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

精灵表.cpp

#include "Stuffcollection.h"
#include "Spritesheet.h"
void Spritesheet::init() {
  Stuffcollection stuffme;
  myvar = stuffme.myfuncTwo();
}

我遵循的一般规则:

  • 不要包含包含中的包含,伙计。如果可能的话,更喜欢远期申报。
    • 例外:将系统包含在您想要的任何位置
  • 让CPP包含它所需要的一切,而不是依赖于H递归地包含它的文件
  • 始终使用防护罩
  • 切勿使用pragma

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