循环C ++头包含

在一个项目中,我有两个类:

// mainw.h

#include "IFr.h" ... class mainw { public: static IFr ifr; static CSize=100; ... }; 

// IFr.h

 #include "mainw.h" ... class IFr { public float[mainw::CSize]; }; 

但是我不能编译这个代码,在static IFr ifr;得到错误static IFr ifr; 线。 这种交叉包含是禁止的吗?

这种交叉包含是禁止的吗?

是。

解决办法是说mainw的ifr成员是一个引用或一个指针,这样一个前向声明就可以代替完整的声明,如:

 //#include "IFr.h" //not this class IFr; //this instead ... class mainw { public: static IFr* ifr; //pointer; don't forget to initialize this in mainw.cpp! static CSize=100; ... } 

或者,在一个单独的头文件中定义CSize值(以便Ifr.h可以包含这个其他头文件而不是包含mainw.h)。

你不能有两个这样embedded对方的类。 你可以让其中的一个指针:

 class foo; class bar { foo* fooPtr; } 

你必须构buildfoo并将其分配给bar的构造函数中的fooPtr,并将其释放到析构函数中 – 这肯定是更多的工作。

或者,在这种情况下,正如其中一位评论者所build议的那样,将mainw :: size作为一个定义并将其放置在某个共同的地方。

你可以做这样的recursion包含,但是一般来说你还需要使用某种头部守护技巧 – 否则预处理器将进入无限recursion。 这不会真的帮助你解决你的根本问题,因为你基本上有两个类,每个类都需要看到另一个的完整声明才能编译:

 class mainw { public: static IFr ifr; // needs to see the full declaration of the Ifr class in order to know the size ... class IFr { public float[mainw::size]; // needs to see the full declaration of mainw in order to know what size is 

无论你先放哪一个,都不能编译,因为需要知道对方的全部细节。

C ++不允许这种循环包含,但这应该起作用:

而不是包含IFr.h,请使用前向声明。

 class IFr; class mainw { //... }; 

这会使mainw编译得很好,但所有使用ifr成员的代码都需要包含IFr.h。

这只适用于因为ifr是一个static成员。 否则,编译器需要知道ifr的确切大小。

而且,正如许多其他人所说的,你应该在两个标题周围都包含警卫,以避免包含相同标题两次的错误。

 #ifndef IFR_H #define IFR_H //... #endif 

你可以做:

 // mainw.h #include "IFr.h" class mainw { public: static const size_t CSize=100; static IFr<CSize> ifr; ... }; // IFr.h template <size_t Sz> struct IFr { float sz_[Sz]; }; 

或者如果CSize需要在运行时更改,请使用@ChrisW答案显示的指针解决scheme。

如果你有

 #ifndef __MYHEADER_NAME_WHICH_IS_RANDOM_PER_FILE_H #define __MYHEADER_NAME_WHICH_IS_RANDOM_PER_FILE_H //... Code.. #endif 

包裹你的代码,那么你应该没问题:)

[编辑]代码拼写:O:P