15

在一个项目中,我有 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;在行出现错误。这种交叉包含是否被禁止?

4

6 回答 6

17

这种交叉包含是否被禁止?

是的。

一种解决方法是说 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)。

于 2009-08-15T11:15:11.567 回答
4

你不能有两个以这种方式相互嵌入的类。您可以将其中一个设为指针:

class foo;

class bar 
{
    foo* fooPtr;
}

您必须构造 foo 并将其分配给 bar 的构造函数中的 fooPtr 并在析构函数中释放它 - 这肯定需要更多的工作。

或者,在这种情况下,正如其中一位评论者所建议的那样,将 mainw::size 定义为一个定义并将其放在常见的地方。

于 2009-08-15T11:15:16.857 回答
1

您可以像这样进行递归包含,但通常您还需要使用某种标头保护技巧 - 否则预处理器将进入无限递归。这不会真正帮助您解决潜在问题,因为您基本上有两个类,每个类都需要查看另一个类的完整声明才能编译:

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

不管你先放哪一个,它都无法编译,因为它需要知道另一个的全部细节。

于 2009-08-15T11:15:27.793 回答
1

C++ 不允许这种循环包含,但这应该有效:

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

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

这将使mainw编译正常,但所有使用该ifr成员的代码也需要包含 IFr.h。

这只有效,因为ifr它是static会员。否则,编译器需要知道ifr.

此外,正如许多其他人所说,您应该在两个标题周围都包含防护措施,以避免由于两次包含相同标题而导致的错误。

#ifndef IFR_H
#define IFR_H
//...
#endif
于 2009-08-15T11:38:13.037 回答
1

你可以做:

// 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 答案所示的指针解决方案。

于 2009-08-15T11:58:27.143 回答
0

如果你有

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

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

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

于 2009-08-15T10:58:15.517 回答