"包含文件过多"错误 C1014

"Too many include files" error C1014

本文关键字:错误 C1014 包含 文件      更新时间:2023-10-16

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

1>k:schoolc++project_2project_2mechanic.h(8): fatal error C1014: too many include files : depth = 1024
1>  Maintenance.cpp
1>k:schoolc++project_2project_2maintenance.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_ */

将包含移动到 IFNDEF 语句中。以递归方式包含文件

猜测一下,我想你有一个循环包含问题正在进行。您的标头之一是否Datum.hWielrenner.hOnderhoud.h包含Fiets.h?或者他们是否包含一个包含它的文件?

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

// top of file
#ifndef INCLUDED_MYFILE_H
#define INCLUDED_MYFILE_H
// ... body of the file ...
#endif
// end of file

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

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

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

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

#ifndef _THIS_HEADER_
#define _THIS_HEADER_
/* contents */
#endif

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

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

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

如果您了解预处理器的工作方式,您可以看到第一次包含标头时,#ifndef 将为真 - 在您的示例中尚未定义"BICYCLE_H_"。 因此,将编译 #ifndef 的主体,首先 #defining"BICYCLE_H_",然后声明要在标头中声明的所有内容。

第二次和任何连续将同一头文件拉入同一编译单元"BICYCLE_H_"时实际上已经在第一次定义,并且 #ifndef 将为 false。 这意味着将跳过文件的整个正文,因此最终结果是,几乎无论您的结构多么复杂,任何标头都将只包含一次。

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

  • (*) #pragma once 在技术上特定于编译器,但得到广泛支持。 它执行与 #ifdefs 相同的目的,因此从技术上讲,您可以选择一个或另一个。 但是,您经常同时看到两者"以防万一"编译器一次不理解 #pragma。

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

你为什么取消评论#pragma once?它是特定于编译器的,其工作原理类似于#ifndef保护。我通常在头文件中同时使用两者。

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

首先,你不需要一次 #pragma,#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_ */