在一个项目中,我有 2 个类:
// 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;
在行出现错误。这种交叉包含是否被禁止?
在一个项目中,我有 2 个类:
// 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;
在行出现错误。这种交叉包含是否被禁止?
这种交叉包含是否被禁止?
是的。
一种解决方法是说 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)。
你不能有两个以这种方式相互嵌入的类。您可以将其中一个设为指针:
class foo;
class bar
{
foo* fooPtr;
}
您必须构造 foo 并将其分配给 bar 的构造函数中的 fooPtr 并在析构函数中释放它 - 这肯定需要更多的工作。
或者,在这种情况下,正如其中一位评论者所建议的那样,将 mainw::size 定义为一个定义并将其放在常见的地方。
您可以像这样进行递归包含,但通常您还需要使用某种标头保护技巧 - 否则预处理器将进入无限递归。这不会真正帮助您解决潜在问题,因为您基本上有两个类,每个类都需要查看另一个类的完整声明才能编译:
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 答案所示的指针解决方案。
如果你有
#ifndef __MYHEADER_NAME_WHICH_IS_RANDOM_PER_FILE_H
#define __MYHEADER_NAME_WHICH_IS_RANDOM_PER_FILE_H
//... Code..
#endif
包裹你的代码,那么你应该没问题:)
[编辑] 代码拼写 :O :P