“包含太多文件”错误C1014

时间:2012-08-14 12:01:17

标签: c++ visual-studio include

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

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)...

项目的示例头文件:bicycle.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_ */

8 个答案:

答案 0 :(得分:9)

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

答案 1 :(得分:4)

猜测一下,我会想象你有一个循环包含问题正在进行中。您的某个标题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

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

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

答案 2 :(得分:2)

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

答案 3 :(得分:2)

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

#ifndef _THIS_HEADER_
#define _THIS_HEADER_

/* contents */

#endif

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

答案 4 :(得分:2)

#pragma once和#ifndef / #define / #endif组合都有相同的用途:防止相同的定义被意外地包含在同一个编译单元中两次。这个结构的可接受名称是"include guard"

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

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

同一个头文件被拉入同一个编译单元的第二个和任何连续时间&#34; BICYCLE_H _&#34;实际上已经是第一次定义,#ifndef将为false。这意味着将跳过文件的整个主体,因此最终结果是几乎 nomatter您的结构有多复杂,任何标头只包含一次。

现在,在您的特定情况下,如果您解决了这个问题,您可能会看到另一个问题:我从包含的大量深度和相对较少的文件中猜测您有一个包含周期某处。例如,bicycle.h可能包含cyclist.h,而cyclist.h又包含了​​bicycle.h,你会得到一个无限的,无法解决的循环。要解决此问题,请查看&#34; forward declaration&#34;例如。

  • (*)#pragma once在技术上是特定于编译器的,但受到广泛支持。它的作用与#ifdefs相同,因此从技术上讲,您可以选择其中一个。但是,你经常会同时看到这两个&#34;以防万一&#34;编译器没有理解#pragma一次。

答案 5 :(得分:0)

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

答案 6 :(得分:0)

为什么要取消注释#pragma once?它是特定于编译器的,与#ifndef警卫的工作方式类似。我通常在头文件中使用它们。

此外,即使在其他#include陈述之前,也要将警卫放在最开始。

答案 7 :(得分:0)

首先,您不需要#pragma一次AND #ifndef包含警卫。只需一个即可。

其次,将你的包含INSIDE包括在内:

#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_ */