循环C ++标题包含

时间:2009-08-15 10:56:11

标签: c++ static include circular-dependency

在一个项目中,我有两个班级:

// 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;行收到错误。是否禁止这种交叉包含?

6 个答案:

答案 0 :(得分:16)

  

是否禁止这种交叉包含?

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

答案 1 :(得分:4)

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

class foo;

class bar 
{
    foo* fooPtr;
}

你必须构造foo并将其分配给bar的构造函数中的fooPtr并在析构函数中释放它 - 这肯定会有点多工作。

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

答案 2 :(得分: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

无论你先放哪一个,它都无法编译,因为它需要知道另一个的完整细节。

答案 3 :(得分:1)

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

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

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

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

这仅适用,因为ifrstatic成员。否则,编译器需要知道ifr的确切大小。

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

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

答案 4 :(得分: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答案显示的指针解决方案。

答案 5 :(得分:0)

如果你有

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

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

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