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

プロジェクトのヘッダー ファイルの例: 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_ */
4

8 に答える 8

9

インクルードを IFNDEF ステートメントに移動します。ファイルを再帰的に含める

于 2012-08-14T12:03:18.130 に答える
4

推測では、循環インクルードの問題が発生していると思います。ヘッダーの 1 つにDatum.h,Wielrenner.hOnderhoud.h含まFiets.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

#pragma once と #ifndef / #define / #endif の組み合わせはどちらも同じ目的を果たします。同じ定義が誤って同じコンパイル単位に 2 回含まれるのを防ぐためです。この構造の受け入れられた名前は、「インクルード ガード」です。

したがって、#pragma once は常にヘッダー ファイルの最初のステートメントにする必要があります*。その直後に #ifndef/#define ペアが続きます。次に、ヘッダー ファイルの内容全体、次に #endif が続きます。

プリプロセッサの仕組みを理解していれば、最初にヘッダーがインクルードされたときに #ifndef が true になることがわかります。この例では、「BICYCLE_H_」はまだ定義されていません。したがって、#ifndef の本体がコンパイルされます。まず #defining "BICYCLE_H_" を実行し、次にヘッダーで宣言するすべてのものを宣言します。

同じヘッダー ファイルが同じコンパイル ユニット "BICYCLE_H_" に取り込まれる 2 回目以降は、実際には最初の時点で既に定義されており、#ifndef は false になります。これは、ファイルの本文全体がスキップされることを意味するため、最終的な結果として、構造がどれほど複雑であっても、ヘッダーは 1 回だけインクルードされます。

さて、あなたの特定のケースでは、この1つの問題を解決すると別の問題が発生する可能性があります.インクルードの深さが大きく、ファイルが比較的少ないことから、どこかにインクルードサイクルがあると思います. たとえば、bicycle.h が、cyclist.h をインクルードし、これが再度 bicycle.h をインクルードすると、解決不能な無限ループが発生します。これを回避するには、たとえば「前方宣言」を見てください。

  • (*) #pragma once は技術的にはコンパイラ固有ですが、広くサポートされています。#ifdefs と同じ目的を実行するため、技術的にはどちらかを選択できます。ただし、コンパイラが #pragma once を理解しない場合に備えて、両方を同時に表示することがよくあります。
于 2012-08-14T12:13:36.583 に答える
2

インクルードを に移動して、#ifndef FIETS_H_何度もインクルードしないようにします。

于 2012-08-14T12:04:24.647 に答える
2

各ヘッダー ファイルの先頭には、インクルード ガードがあります。

#ifndef _THIS_HEADER_
#define _THIS_HEADER_

/* contents */

#endif

各ヘッダーがコンパイル単位ごとに 1 回含まれていることを確認します。

于 2012-08-14T12:04:58.953 に答える
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 にはガードが含まれています。1つだけで十分です。

次に、インクルード ガードの内側にインクルードを配置します。

#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 に答える