C++ では、「メイン」ファイルにクラス ファイルのヘッダーを含める規則は何ですか。例えば
myclass.h
class MyClass {
doSomething();
}
myclass.cpp
doSomething() {
cout << "doing something";
}
run.cpp
#include "myclass.h"
#include "myclass.cpp"
etc..
これは比較的標準的なものですか?
.cpp ファイルは含めず、.h ファイルのみを含めます。.cpp の関数定義は .obj ファイルにコンパイルされ、最終的なバイナリにリンクされます。.cpp ファイルを他の .cpp ファイルに含めると、同じ関数定義がコンパイルされた 2 つの異なる .obj ファイルが生成され、リンカー エラーが発生します。
1 つの .cpp ファイルと、それに含まれるすべてのヘッダーが 1 つの翻訳単位を構成していると言えます。名前が示すように、1 つの翻訳単位が単独でコンパイルされます。各翻訳単位の結果 (多くの場合、file.o または file.obj と呼ばれます) は、リンカーによってリンクされ、まだ解決されていない参照が修正されます。だからあなたの場合、あなたは持っています
Translation Unit 1 = run.cpp: myclass.h ...
Translation Unit 2 = myclass.cpp: myclass.h ...
クラス定義が両方の翻訳単位に表示されます。しかし、それは問題ありません。両方のクラスが等しく定義されている限り、許可されます。ただし、関数がインラインでない場合、同じ関数を 2 つの翻訳単位に表示することはできません。インライン関数は、1 つの翻訳単位で 1 回だけ定義できるわけではありません。次に、リンカーに各翻訳単位の結果を取得させ、それらを実行可能ファイルにバインドします。
Executable = mystuff: run.o myclass.o ...
この質問に対する多くの適切な回答については、Understanding C Compilersを参照してください。
cpp ファイルは個別にコンパイルします。特定の cpp ファイルを 2 つ以上の cpp ファイルに含めると、リンク フェーズ中に競合が発生する可能性があります。
1 つの *.cpp を別の *.cpp 内に含めないでください。その代わり:
myclass.h
class MyClass {
doSomething();
}
myclass.cpp
#include "myclass.h"
MyClass::doSomething() {
cout << "doing something";
}
run.cpp
#include "myclass.h"
etc..
myclass.cpp を main.cpp 内に含める (コンパイラが両方を 1 つのパスで認識できるようにする) 代わりに、myclass.cpp と main.cpp を別々にコンパイルしてから、「リンカー」でそれらを 1 つの実行可能ファイルに結合させます。
通常、.cpp ファイルを個別にコンパイルし、結果の .o を他の .o とリンクします。
したがって、myclass.cpp には myclass.h が含まれ、ユニットとしてコンパイルされます。