私はいつも*.h
クラス定義にファイルを使用していましたが、いくつかのブースト ライブラリ コードを読んだ後、それらはすべて を使用していることに気付きました*.hpp
。私はいつもそのファイル拡張子に嫌悪感を抱いていましたが、それは主に私がそれに慣れていないためだと思います.
*.hpp
overを使用する利点と欠点は何*.h
ですか?
C ヘッダーと C++ ヘッダーの名前が異なる理由はいくつかあります。
C は C++ ではないことを覚えておいてください。自分が何をしているのかを理解していない限り、混ぜ合わせるのは非常に危険です。ソースに適切な名前を付けると、言語を区別するのに役立ちます。
私が .hpp を使用するのは、どのヘッダーが C++ ヘッダーで、どのヘッダーが C ヘッダーであるかをユーザーに区別してもらいたいからです。
これは、プロジェクトが C と C++ の両方のモジュールを使用している場合に重要です: 他の誰かが私の前に説明したように、非常に慎重に行う必要があり、拡張機能を通じて提供する「契約」から始まります。
(または .hxx、または .hh、または何でも)
このヘッダーは C++ 専用です。
C モジュールを使用している場合は、それを含めようとさえしないでください。C フレンドリーにするための努力が行われていないため、気に入らないでしょう (関数のオーバーロード、名前空間などのように、失われるものが多すぎます)。
このヘッダーは、C ソースと C++ ソースの両方に直接または間接的に含めることができます。
__cplusplus
マクロで保護されているため、直接含めることができます。
extern "C"
ます。例えば:
#ifndef MY_HEADER_H
#define MY_HEADER_H
#ifdef __cplusplus
extern "C"
{
#endif
void myCFunction() ;
#ifdef __cplusplus
} // extern "C"
#endif
#endif // MY_HEADER_H
extern "C"
または、宣言でそれを囲む対応する .hpp ヘッダーによって間接的に含めることもできます。
例えば:
#ifndef MY_HEADER_HPP
#define MY_HEADER_HPP
extern "C"
{
#include "my_header.h"
}
#endif // MY_HEADER_HPP
と:
#ifndef MY_HEADER_H
#define MY_HEADER_H
void myCFunction() ;
#endif // MY_HEADER_H
私はいつも、ヘッダーはファイルとファイル.hpp
の一種のかばん語であると考えていました...実装の詳細も含むヘッダーです。 .h
.cpp
.hpp
通常、拡張子として見た (そして使用した) 場合、対応する.cpp
ファイルはありません。.hpp
他の人が言ったように、これは厳格な規則ではなく、私がファイルをどのように使用するかだけです。
どの拡張機能を使用するかは問題ではありません。どちらでもOKです。
私*.h
は C と*.hpp
C++ に使用します。
EDIT [Dan Nissenbaum からの提案を追加]:
ある規則では、ヘッダー自体でプロトタイプが定義されている場合、.hpp ファイルが使用されます。コンパイラはテンプレートのインスタンス化時にのみ各タイプのコードを生成するため、ヘッダーでのこのような定義はテンプレートの場合に役立ちます。したがって、それらがヘッダー ファイルで定義されていない場合、それらの定義はリンク時に他のコンパイル ユニットから解決されません。プロジェクトがテンプレートを多用する C++ のみのプロジェクトである場合、この規則が役立ちます。
この規則に従う特定のテンプレート ライブラリは、対応する .cpp ファイルがないことを示すために、ヘッダーに .hpp 拡張子を提供します。
もう 1 つの規則は、C ヘッダーに .h を使用し、C++ に .hpp を使用することです。良い例はブースト ライブラリです。
Boost FAQ からの引用、
ファイル拡張子は、ファイルの「タイプ」を人間とコンピュータ プログラムの両方に伝えます。'.h' 拡張子は C ヘッダー ファイルに使用されるため、C++ ヘッダー ファイルについて誤った情報を伝えます。拡張子を使用しないと、何も伝達されず、ファイルの内容を検査してタイプを判断する必要があります。'.hpp' を使用すると、明確に C++ ヘッダー ファイルとして識別され、実際にはうまく機能します。(ライナー・デイク)
この同じOPに対する「user1949346」の回答に対する私のコメントを指摘するために、これをリマインダーとして回答しています。
多くの人がすでに答えているように、どちらの方法でも問題ありません。続いて、自身の印象を強調します。
はじめに、以前の名前付きコメントで述べたように、私の意見は、実際に反対の理由がない場合、C++
ヘッダー拡張が提案されているということです。.h
ISO/IEC ドキュメントではこのヘッダー ファイルの表記法が使用されているため、 との文字列の一致.hpp
は言語ドキュメントでも発生しませんC++
。
しかし、私は現在、どちらの方法でも問題ない理由、特にそれ自体が言語の主題ではない理由について、承認可能な理由を目指しています。
それでは、行きましょう。
ドキュメント (実際にはC++
バージョン N3690 から参照しています) では、ヘッダーは次の構文に準拠する必要があると定義されています。
2.9 ヘッダー名
header-name: < h-char-sequence > " q-char-sequence " h-char-sequence: h-char h-char-sequence h-char h-char: any member of the source character set except new-line and > q-char-sequence: q-char q-char-sequence q-char q-char: any member of the source character set except new-line and "
したがって、この部分から抽出できるように、ヘッダー ファイル名もソース コードで有効な名前であれば何でもかまいません。文字を含むことを除い'\n'
て、それが含まれるかどうかに応じて<>
、>
. または、""
-include によって含まれている場合は、"
.
つまり、 のようなファイル名をサポートする環境がある場合prettyStupidIdea.>
、次のようなインクルードを使用します。
#include "prettyStupidIdea.>"
有効ですが、次のとおりです。
#include <prettyStupidIdea.>>
無効になります。逆も同じです。
さらには
#include <<.<>
有効なインクルード可能なヘッダー ファイル名になります。
これでも に準拠しC++
ますが、かなりばかげた考えです。
そしてそれ.hpp
が有効な理由でもあります。
しかし、それは言語の決定を設計する委員会の結果ではありません!
したがって、使用について議論することは、 、またはこのトピックに関する他の投稿で読んだこと.hpp
と同じです。.cc
.mm
.hpp
どこから来たのか手がかりがないことを認めなければなりません1、しかし、いくつかの解析ツール、IDE、または関係のある何かの発明者が、いくつC++
かの内部プロセスを最適化するか、いくつかを発明するためにこのアイデアに来たに違いありません(おそらくそれらのためにも必然的に) ) 新しい命名規則。
しかし、それは言語の一部ではありません。
そして、このように使用することを決定したときはいつでも。彼がそれを最も気に入っているからかもしれませんし、ワークフローの一部のアプリケーションがそれを必要としているからかもしれませんが、それは決して言語の要件ではありません。したがって、「pp は C++ で使用されるため」と言う人は誰でも、言語の定義に関しては単に間違っています。
C++ では、前の段落に関するすべてが許可されます。また、委員会が使用を提案したものがある場合.h
、これは ISO ドキュメントのすべての例で訴えられている拡張であるため、使用しています。
結論:
.h
over.hpp
またはその逆を使用する必要性を見たり感じたりしない限り、気にする必要はありません。どちらも、標準に関して同じ品質の有効なヘッダー名を形成するためです。したがって、使用する必要.h
があるもの、または.hpp
標準の追加の制限であり、相互に準拠していない他の追加の制限と矛盾する可能性さえあるもの. しかし、OPは追加の言語制限について言及していないため、これが質問に対する唯一の正しく承認可能な回答です
"クラス定義の *.h または *.hpp " は次のとおりです。
外部の制限が存在しない限り、どちらも等しく正しく、適用可能です。
1私の知る限り、どうやら、その拡張機能を思いついたのはブースト フレームワークです。.hpp
2もちろん、いくつかの将来のバージョンで何がもたらされるかはわかりません!
最近*.hpp
、c++ ヘッダーに使い始めました。
その理由は、私が主なエディターとして emacs を使用していて、ファイルをロードすると自動的に c モードに入り、*.h
ファイルをロードすると c++ モードになるから*.hpp
です。
*.h
その事実を除けば、どちらか一方を選択する正当な理由は見当たりません*.hpp
。
インクルードは好きなように呼び出すことができます。
でフルネームを指定するだけです#include
。
.h
C を使用する場合は を使用し、C++ を使用する場合はを使用することをお勧めします.hpp
。
それは最終的には単なるコンベンションです。
私は C++ 用の .hpp を好みます。これは、C ヘッダー ファイルではなく C++ ヘッダーであることをエディターと他のプログラマーの両方に明確にするためです。
C++ ("C Plus Plus") は .cpp として意味があります
拡張子が .hpp のヘッダー ファイルを持つ場合、同じ論理フローはありません。
Codegear C++Builder は、Delphi ソース ファイルから自動的に生成されたヘッダー ファイルに .hpp を使用し、「独自の」ヘッダー ファイルに .h ファイルを使用します。
そのため、C++ ヘッダー ファイルを作成するときは、常に .h を使用します。
Bjarne Stroustrup と Herb Sutter は、 https ://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#S-sourceにあるC++ コア ガイドラインで、この質問に対する声明を出しています。標準拡張 (C++11、C++14 など)
SF.1: Y プロジェクトがまだ別の規則に従っていない場合は、コード ファイルには .cpp 接尾辞を使用し、インターフェイス ファイルには .h を使用します。
久々の大会です。ただし、一貫性はより重要であるため、プロジェクトで他のものを使用する場合は、それに従ってください。ノート
この規則は、一般的な使用パターンを反映しています。ヘッダーは、通常は .h を使用する C++ と C の両方としてコンパイルするために C と共有されることが多く、目的のヘッダーだけに異なる拡張子を付けるよりも、すべてのヘッダーに .h という名前を付ける方が簡単です。一方、実装ファイルが C と共有されることはめったにないため、通常は .c ファイルと区別する必要があるため、通常はすべての C++ 実装ファイルに別の名前 (.cpp など) を付けるのが最善です。
特定の名前 .h および .cpp は必須ではなく (デフォルトとして推奨されるだけです)、他の名前が広く使用されています。例は、.hh、.C、および .cxx です。これらの名前は同等に使用してください。このドキュメントでは、実際の拡張子は異なる場合がありますが、.h および .cpp > をヘッダーおよび実装ファイルの省略形として参照します。
IDE (使用している場合) は、十分性について強い意見を持っている場合があります。
ブーストのような人気のあるライブラリを使用している場合、一貫性はすでに壊れており、.hpp を使用する必要があるため、私はこの規則の大ファンではありません。
90 年代初頭の私の仕事の 1 つで、ソース ファイルとヘッダー ファイルにそれぞれ .cc と .hh を使用していました。おそらく、入力するのが最も簡単だからでしょう。
私が .h を使用するのは、それが Microsoft が使用するものであり、Microsoft のコード ジェネレーターが作成するものだからです。穀物に逆らう必要はありません。
特定の拡張機能に利点はありませんが、それがあなた、コンパイラ、および/またはツールにとって異なる意味を持つ可能性があることを除けば. header.h
有効なヘッダーです。 header.hpp
有効なヘッダーです。 header.hh
有効なヘッダーです。 header.hx
有効なヘッダーです。 h.header
有効なヘッダーです。 this.is.not.a.valid.header
拒否の有効なヘッダーです。 ihjkflajfajfklaf
有効なヘッダーです。名前がコンパイラによって適切に解析され、ファイル システムがそれをサポートしている限り、それは有効なヘッダーであり、その拡張子の唯一の利点は、何を読み取るかです。
そうは言っても、拡張子に基づいて正確に推測できることは非常に便利なので、ヘッダー ファイルにはわかりやすい一連のルールを使用することが賢明です。個人的には、次のようなことをするのが好きです。
.h
. あいまいさはありません。.h
取得します。.hpp
.hh
もちろん、これは拡張機能を処理する多くの方法の 1 つにすぎず、物事が単純に見えても、最初の印象を必ずしも信頼できるとは限りません。たとえば、.h
通常のヘッダー、およびテンプレート化された.tpp
クラス メンバー関数の定義のみを含むヘッダー.h
に使用するという言及を見てきました。関数宣言と定義)。別の例として、非常に多くの人が、あいまいになる可能性がない場合でも、常にヘッダーの言語をその拡張子に反映しています。彼らにとって、は常に C ヘッダーおよび(または、または.tpp
.h
.h
.hpp
.hh
.hxx
など) は常に C++ ヘッダーです。.h
繰り返しますが、「ソースファイルに関連付けられたヘッダー」と.hpp
「すべての関数がインラインで定義されたヘッダー」に使用する人もいます。
これを考慮すると、主な利点は、一貫して同じスタイルでヘッダーに名前を付け、そのスタイルをコードを調べている人にすぐにわかるようにすることです。これにより、通常のコーディング スタイルに精通している人なら誰でも、指定された拡張機能が何を意味するのかを一目見ただけで判断できるようになります。
「The C++ Programming Language, Third Edition by Bjarne Stroustrup」では、nº1 必読の C++ の本で、彼は *.h を使用しています。したがって、ベスト プラクティスは *.h を使用することだと思います。
ただし、*.hpp も問題ありません。
ソース ファイルの拡張子は、ビルド システムにとって意味がある場合があります。たとえば、.cpp
または.c
ファイルの makefile にルールがある場合や、コンパイラ (Microsoftcl.exe
など) が拡張子に応じてファイルを C または C++ としてコンパイルする場合があります。
ディレクティブにはファイル名全体を指定する必要があるため#include
、ヘッダー ファイルの拡張子は関係ありません。.c
必要に応じて、ファイルを別のソース ファイルに含めることができます。これは単なるテキスト インクルードであるためです。コンパイラには、これを明確にする前処理された出力をダンプするオプションがある場合があります (Microsoft:/P
ファイルへの前処理、/E
への前処理、ディレクティブの省略、コメントの保持)stdout
/EP
#line
/C
.hpp
C++ 環境にのみ関連するファイル、つまり、C でコンパイルされない機能を使用するファイルに使用することを選択できます。