サーチ…
備考
C ++では、Cと同様に、C ++コンパイラとコンパイルプロセスでCプリプロセッサが使用されます。 GNU Cプリプロセッサマニュアルで指定されているように、ヘッダファイルは次のように定義されています:
ヘッダファイルは、複数のソースファイル間で共有されるC宣言とマクロ定義(マクロを参照)を含むファイルです。 Cのプリプロセスディレクティブ '#include'を使用して、ヘッダファイルをプログラムに含めることによって、ヘッダファイルの使用を要求します。
ヘッダーファイルには2つの目的があります。
- システムヘッダファイルは、オペレーティングシステムの各部へのインタフェースを宣言します。システムコールとライブラリを呼び出すために必要な定義と宣言を提供するために、これらをプログラムに含めます。
- 独自のヘッダファイルには、プログラムのソースファイル間のインタフェースの宣言が含まれています。関連する宣言とマクロ定義のグループがある場合、そのすべてまたは大部分が複数の異なるソースファイルで必要になるたびに、そのためのヘッダーファイルを作成することをお勧めします。
ただし、Cプリプロセッサ自体には、ヘッダファイルもソースファイルと同じです。
ヘッダー/ソースファイルの組織化スキームは、インターフェイスと実装の分離を提供するために、さまざまなソフトウェアプロジェクトによって設定された強く保持された標準的な慣例です。
C ++標準によって正式に強制されるわけではありませんが、ヘッダー/ソースファイルのコンベンションに従うことを強くお勧めします。実際には、すでに遍在しています。
ヘッダーファイルは、将来のC ++標準(例えばC ++ 20など)に含まれると考えられるモジュールの今後の機能によって、プロジェクトファイル構造の規約として置き換えられることに注意してください。
基本的な例
次の例は、 // filename
コメントで示されるように、いくつかのソースファイルに分割されるコードブロックを含みます。
ソースファイル
// my_function.h
/* Note how this header contains only a declaration of a function.
* Header functions usually do not define implementations for declarations
* unless code must be further processed at compile time, as in templates.
*/
/* Also, usually header files include preprocessor guards so that every header
* is never included twice.
*
* The guard is implemented by checking if a header-file unique preprocessor
* token is defined, and only including the header if it hasn't been included
* once before.
*/
#ifndef MY_FUNCTION_H
#define MY_FUNCTION_H
// global_value and my_function() will be
// recognized as the same constructs if this header is included by different files.
const int global_value = 42;
int my_function();
#endif // MY_FUNCTION_H
// my_function.cpp
/* Note how the corresponding source file for the header includes the interface
* defined in the header so that the compiler is aware of what the source file is
* implementing.
*
* In this case, the source file requires knowledge of the global constant
* global_value only defined in my_function.h. Without inclusion of the header
* file, this source file would not compile.
*/
#include "my_function.h" // or #include "my_function.hpp"
int my_function() {
return global_value; // return 42;
}
ヘッダーファイルは、ヘッダーインターフェイスで定義された機能を使用する他のソースファイルに含まれますが、その実装についての知識は必要ありません(コード結合を減らす)。次のプログラムは、上で定義したヘッダmy_function.h
を使用します。
// main.cpp
#include <iostream> // A C++ Standard Library header.
#include "my_function.h" // A personal header
int main(int argc, char** argv) {
std::cout << my_function() << std::endl;
return 0;
}
コンパイルプロセス
ヘッダーファイルはしばしばコンパイルプロセスワークフローの一部であるため、ヘッダー/ソースファイルの規則を使用する一般的なコンパイルプロセスでは、通常次の処理を行います。
ヘッダーファイルとソースコードファイルがすでに同じディレクトリにあると仮定すると、プログラマは次のコマンドを実行します。
g++ -c my_function.cpp # Compiles the source file my_function.cpp
# --> object file my_function.o
g++ main.cpp my_function.o # Links the object file containing the
# implementation of int my_function()
# to the compiled, object version of main.cpp
# and then produces the final executable a.out
あるいは、最初にmain.cpp
をオブジェクトファイルにコンパイルしてから、最後のステップとしてオブジェクトファイルのみをリンクする場合は、 main.cpp
ようにします。
g++ -c my_function.cpp
g++ -c main.cpp
g++ main.o my_function.o
ヘッダーファイルのテンプレート
テンプレートは、コンパイル時にコードを生成する必要があります。たとえば、テンプレート化された関数がソースコードで使用されるとパラメータ化されると、テンプレート化された関数は複数の異なる関数に効果的に変換されます。
つまり、テンプレート化されたコンストラクトを使用するコードでは、一般に任意の派生コードを生成するためにその定義に関する知識が必要となるため、テンプレート関数、メンバ関数、およびクラス定義を別々のソースコードファイルに委任することはできません。
したがって、テンプレート化されたコードは、ヘッダに置かれていれば、その定義をも含んでいなければなりません。その一例を以下に示します。
// templated_function.h
template <typename T>
T* null_T_pointer() {
T* type_point = NULL; // or, alternatively, nullptr instead of NULL
// for C++11 or later
return type_point;
}