0

我收到以下无法解决的错误。

1>k:\school\c++\project_2\project_2\mechanic.h(8): fatal error C1014: too many include files : depth = 1024
1>  Maintenance.cpp
1>k:\school\c++\project_2\project_2\maintenance.h(8): fatal error C1014: too many include files : depth = 1024
(continues for many other files in the project)...

项目中的示例头文件:bike.h

//#pragma once      //Make sure it's included only once

using namespace std;
#include <iostream>

#include "Date.h"
#include "Cyclist.h"
#include "Maintenance.h"

#ifndef BICYCLE_H_
#define BICYCLE_H_

class Bicycle
{
public:
Bicycle(Date, int, int, Cyclist);
~Bicycle(void);
    Datum   getDateJoined() const;
    int getFrameSize() const;
    int getBicycleID() const;
    Cyclist getCyclist();

    void    setDateJoined(Date);
    void    setFrameSize(int);

private:
Date dateJoined;
int frameSize;
int bicycleID;
Cyclist cyclist;
list<Maintenance> maintenanceNotes;
};

#endif /* BICYCLE_H_ */
4

8 回答 8

9

将您的包含移动到 IFNDEF 语句中。您递归地包含您的文件

于 2012-08-14T12:03:18.130 回答
4

猜测一下,我想你有一个循环包含问题。您的标题之一是否Datum.h包含任何机会?或者他们是否包含一个包含它的文件?Wielrenner.hOnderhoud.hFiets.h

您可以通过确保您的标头 - 包括任何包含的标头 - 由预处理器包含保护器保护来避免这种情况,例如

// top of file
#ifndef INCLUDED_MYFILE_H
#define INCLUDED_MYFILE_H

// ... body of the file ...

#endif
// end of file

这将防止您的文件多次包含在编译单元中。

您可能会发现您的构建工具包含一个显示包含树的选项,该选项可以帮助您了解正在发生的事情。

于 2012-08-14T12:07:32.303 回答
2

将包含移入#ifndef FIETS_H_以避免多次包含它们。

于 2012-08-14T12:04:24.647 回答
2

在每个头文件的开头,都有一个包含保护:

#ifndef _THIS_HEADER_
#define _THIS_HEADER_

/* contents */

#endif

确保每个编译单元的每个标头都包含一次。

于 2012-08-14T12:04:58.953 回答
2

#pragma once 和 #ifndef / #define / #endif 组合都具有相同的目的:防止相同的定义被意外包含两次到相同的编译单元中。这种结构的公认名称是“包含守卫”

因此,#pragma once 应该始终是头文件中的第一个语句*,紧随其后的是 #ifndef/#define 对。然后跟随头文件的全部内容,然后是#endif。

如果您了解预处理器的工作方式,您会看到第一次包含标头时,#ifndef 将为真 - 在您的示例中“BICYCLE_H_”尚未定义。因此#ifndef 的主体将被编译,首先#defining "BICYCLE_H_" 然后声明所有你想在头文件中声明的东西。

同一头文件被拉入同一编译单元“BICYCLE_H_”的第二次和任何连续时间实际上已经在第一次定义,并且#ifndef 将为假。这意味着文件的整个正文将被跳过,因此最终结果是几乎不管你的结构有多复杂,任何标题都只会被包含一次。

现在,在您的特定情况下,如果您解决了这个问题,您可能会看到另一个问题:我从大量的包含和相对较少的文件中猜测您在某处有一个包含循环。例如,bike.h 可能包含 cyclist.h,而后者又包含了 bike.h,你会得到一个无限的、无法解决的循环。要解决此问题,请查看“前向声明”示例。

  • (*) #pragma once 在技术上是特定于编译器的,但得到广泛支持。它执行与#ifdefs 相同的目的,因此从技术上讲,您可以选择其中一个。但是,您经常会同时看到两者“以防万一”编译器一次不理解#pragma。
于 2012-08-14T12:13:36.583 回答
0

我从来没有达到包含文件数量的限制,我目前正在研究 1M LOC。我最好的猜测是你有一个包含循环:文件 X 包含 Y,Y(直接或间接)包含 X。

于 2012-08-14T12:04:42.383 回答
0

你为什么取消评论#pragma once?它是特定于编译器的,工作方式类似于#ifndef守卫。我通常在头文件中使用两者。

此外,将警卫放在最开始,甚至在其他#include语句之前。

于 2012-08-14T12:05:22.427 回答
0

首先,您不需要 #pragma once 并且 #ifndef 包含警卫。一个就足够了。

其次,将您的包含放在包含保护中:

#ifndef BLAH_H
#define BLAH_H
#include <stuff>
#endif // BLAH_H

第三,为什么不在标题中声明需要的类,然后将它们包含在源中?

#ifndef BICYCLE_H_
#define BICYCLE_H_

class Date;
class Cyclist;
class Maintenance;

class Bicycle
{
public:
Bicycle(Date, int, int, Cyclist);
~Bicycle(void);
    Datum   getDateJoined() const;
    int getFrameSize() const;
    int getBicycleID() const;
    Cyclist getCyclist();

    void    setDateJoined(Date);
    void    setFrameSize(int);

private:
Date dateJoined;
int frameSize;
int bicycleID;
Cyclist cyclist;
list<Maintenance> maintenanceNotes;
};

#endif /* BICYCLE_H_ */
于 2012-08-14T13:06:01.387 回答