2

ヘッダーファイルをインクルードすると、次のようになります。

//myheader.h
#ifndef MY_HEADER_H
#define MY_HEADER_H

//....

#endif

の中へ、

//mycpp1.cpp
#include "myheader.h"

私が言われたことは、mycpp1.cpp が myheader.hMY_HEADER_Hをインクルードすると定義されるため、再度インクルードしようとすると false になるということです。

今、それを mycpp2.cpp に含めたい場合。

//mpcpp2.cpp
#include "myheader.h"

それは含まれますか、それとも最初に含まれたときと同じ宣言を使用しますか?

4

5 に答える 5

6

プリプロセッサの定義は、ファイルごとに個別です。したがって、#includemyheader.h を 2 つの別個の .cpp ファイルに分割すると、1 回ではなく 2 回インクルードされます。.cpp ごとに 1 つ。

于 2011-12-03T05:31:31.430 に答える
4

プリプロセッサの定義は、現在のコンパイル単位に対してローカルです。

もちろん複雑なケースもありますが、ポイントは次のとおりです。

.cpp (ソース) ファイルを個別のエンティティとして見るようにしてください。本当に奇妙なことをしなければ、気になるものを除いてすべての .cpp ファイルを削除すれば、コンパイル段階では定義は必要なく、ものの名前 (宣言) だけを気にするため、コンパイルできます。

したがって、N 個のソース ファイルを 1 回の実行でコンパイルすると、基本的に次のようになります。

[ *.H + SOURCE1.CPP ] --> SOURCE1.O
[ *.H + SOURCE2.CPP ] --> SOURCE2.O
...
[ *.H + SOURCEN.CPP ] --> SOURCEN.O

ここで、すべての行は個別のコンパイル単位であり、SourceX.CPP と含まれているヘッダーをオブジェクト ファイルにレンダリングします。それで、ここにN個の別のものがあります。

このように、共通ヘッダーを変更しない場合、変更されていないソース ファイルを再コンパイルする必要はありません。もちろん、ソース ファイルを変更した場合は、それを再コンパイルする必要があります。最後に、共通ヘッダーを変更する場合は、それを含むすべてのソース ファイルを再コンパイルする必要があります。ここで、コンパイル フェーズの前に、すべての #inlude "filename.ext"行 (プリプロセッサ ディレクティブ) が filename.ext ファイルの正確な内容に置き換えられることに注意する必要があります。

次に、リンクは別の問題です。その段階での目標は、その N 個のオブジェクト ファイルから 1 つのファイルを作成することです。(繰り返しますが、これは単純なケースです)

これはリンクしています:

[ SOURCE1.O + SOURCE2.O + ... + SOURCEN.O ]  --> EXECUTABLE.FILE

影響を受けるオブジェクト ファイルが、値とアルゴリズム (関数定義) のバッグであると想像してください。たとえば、バッグのどこかに正確に 1 つの main関数 (定義) が存在する必要があるため、リンカーは、プログラムを実行するときに何をすべきかを確実に認識します。

あなたがそれを手に入れたことを願っています

グローバル関数の定義をヘッダー ファイルに書き込んで、それを 2 つの別々のコンパイル ユニットにインクルードすると、それらをリンクしようとするとどうなるでしょうか。

答え: リンカー エラー - 複数の定義。それらは個別にコンパイルできるためです。

于 2011-12-03T06:09:24.143 に答える
3

MY_HEADER_Hが mycpp1.cpp で定義されているだけの場合、ヘッダー ファイルは mycpp2.cpp に含まれます。

トリックの実際の目的は次のとおりです。

header1.hにはheader2.hが含まれます。
したがって、 mycpp.cpp にheader1.hheader2.hの両方をインクルードすると、このトリックを行わないと、header2.h が 2 回インクルード されます。

于 2011-12-03T05:36:59.283 に答える
1

他の人が述べたように、ヘッダー ファイルは .cpp ファイルごとに 1 回含まれます。しかし、これの全体的な目的についても言及したかった:

#ifndef MY_HEADER_H
#define MY_HEADER_H
// ..
#end if

これが問題を引き起こさないようにすることです

mycpp1.cpp

#include "myheader.h"
#include "myheader.h"
// ...

私が始めたときに私が問題を抱えていたもう1つのことは、ヘッダーファイルを複数の.cppファイルに含め、その中にグローバル変数を定義したときでした...これを解決するために私がすることは...

myheader.h

#ifdef MY_HEADER_H
#define MY_HEADER_H

#ifdef GLOBAL_EXTERN
extern int nGlobalInt;
#else
int nGlobalInt = 282;
#endif

#endif

mycpp1.cpp

#include "myheader.h"
// ...

cout << nGlobalInt;

mycpp2.cpp

#define GLOBAL_EXTERN
#include "myheader.h"
// ...

cout << nGlobalInt;

両方の cpp ファイルが印刷されます282

于 2011-12-03T05:46:51.590 に答える
-1

1回のみの収録となります。ディレクティブ MY_HEADER_H は最初のインクルードで定義され、その後の#includemyheader.h へのすべての試みは効果がありません。

プリプロセッサ ディレクティブはファイル全体に適用されます。そうしないと、たとえば、myheader.h で宣言されたすべてのクラスが再定義されます。

于 2011-12-03T05:44:56.470 に答える