循环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