回答:
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
編集 [Dan Nissenbaumからの提案を追加]:
1つの規則では、プロトタイプがヘッダー自体で定義されるときに.hppファイルが使用されます。コンパイラーはテンプレートのインスタンス化時にのみ各タイプのコードを生成するため、このようなヘッダーの定義はテンプレートの場合に役立ちます。したがって、それらがヘッダーファイルで定義されていない場合、それらの定義はリンク時に他のコンパイルユニットから解決されません。プロジェクトが、テンプレートを多用するC ++のみのプロジェクトである場合、この規則が役立ちます。
この規則に準拠している特定のテンプレートライブラリは、ヘッダーに.hpp拡張子を付けて、対応する.cppファイルがないことを示します。
別の規則は、Cヘッダーに.hを使用し、C ++に.hppを使用することです。良い例は、boostライブラリです。
Boost FAQからの引用、
ファイル拡張子は、人間とコンピュータプログラムの両方にファイルの「タイプ」を伝えます。'.h'拡張子はCヘッダーファイルに使用されるため、C ++ヘッダーファイルについて誤った情報を伝えます。拡張子を使用しないと、何も通信せず、ファイルの内容を検査してタイプを判別します。'.hpp'を使用すると、それがC ++ヘッダーファイルとして明確に識別され、実際の作業でうまく機能します。(レイナー・デイケ)
私は最近使い始めました *.hpp
c ++ヘッダーのをました。
その理由は、私はプライマリエディタとしてemacsを使用しており、*.h
ファイルをロードすると自動的にcモードになり、ファイルをロードするとc ++モードになり*.hpp
ます。
その事実を除けば、私が選択すること*.h
、*.hpp
またはその逆を選択することには十分な理由がありません。
私は、これと同じ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
またはこのトピックの他の投稿で他に読んだです。
私は1.hpp
からどこに来たのか手掛かりがないことを認めなければなりませんが、いくつかの解析ツールやIDEの発明者がこのアイデアを思いついて、いくつかの内部プロセスを最適化したり、単に発明したりしたのでしょう(おそらくそれらについてもおそらく) )新しい命名規則。C++
しかし、それは言語の一部ではありません。
そして、この方法でそれを使用することを決定したときはいつでも。彼が最もそれを好きか、ワークフローのいくつかのアプリケーションがそれを必要とするので、それは決してので、それはかもしれ2は、言語の要件ではありません。したがって、「ppはC ++で使用されるためです」と言う人は、言語の定義に関しては単に間違っています。
C ++では、前の段落を尊重するものはすべて許可されます。そして、委員会が使用することを提案したものがあれば、それは.h
ISOドキュメントのすべての例で訴えられた拡張であるため、それを使用しています。
結論:
.h
over を使用し.hpp
たり、その逆を使用したりする必要がまったくない、または感じない限り、気にする必要はありません。どちらも標準に関して同じ品質の有効なヘッダー名を形成するからです。したがって、何もREQUIRES使用することができ.h
たり.hpp
しても、他の追加の制限と矛盾することができ、相互に適合していない標準の追加の制限です。しかし、OPは追加の言語制限について言及していないため、これが質問に対する唯一の正しい承認可能な回答です
" クラス定義の* .hまたは* .hpp "は:
外部の制限が存在しない限り、どちらも同様に正しく適用可能です。
1 私が知っていることから、明らかに、その.hpp
拡張機能を思いついたのはブーストフレームワークです。
2 もちろん、将来のいくつかのバージョンで何がもたらされるかは言えません!
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を使用します。
それは長年の慣習です。ただし、一貫性がより重要であるため、プロジェクトで他の何かを使用する場合は、それに従ってください。注意
この規則は、一般的な使用パターンを反映しています。ヘッダーはCと共有され、C ++とCの両方としてコンパイルされることが多く、通常は.hを使用します。意図するヘッダーだけに異なる拡張子を付けるよりも、すべてのヘッダーに.hという名前を付ける方が簡単です。一方、実装ファイルがCと共有されることはほとんどないため、通常は.cファイルと区別する必要があるため、通常はすべてのC ++実装ファイルに別の名前(.cppなど)を付けることをお勧めします。
特定の名前.hと.cppは必須ではなく(デフォルトとして推奨されるだけです)、他の名前が広く使用されています。例は、.hh、.C、および.cxxです。そのような名前は同等に使用してください。このドキュメントでは、実際の拡張子が異なる場合でも、.hおよび.cpp>をヘッダーファイルと実装ファイルの省略形と呼びます。
IDE(使用している場合)は、十分性について強い意見を持っている場合があります。
boostのような人気のあるライブラリを使用している場合、一貫性はすでに壊れているため、.hppを使用する必要があるため、私はこの規則の大ファンではありません。
.hを使用しているのは、それがMicrosoftが使用し、コードジェネレーターが作成するものだからです。穀物に逆らう必要はありません。
「C ++プログラミング言語、Bjarne Stroustrupによる第3版」では、nº1必読のC ++の本で、彼は* .hを使用しています。したがって、ベストプラクティスは* .hを使用することだと思います。
ただし、*。hppも問題ありません。
.hpp
言語自体による言及がまったくないため、これは有効なポイントでした。
ツールと人間が何かを区別するのは簡単です。それでおしまい。
従来の使用(ブーストなどによる)では、.hpp
特にC ++ヘッダーです。一方、.h
非C ++のみのヘッダー(主にC)用です。重要なケースが多数あるため、コンテンツの言語を正確に検出することは一般に困難です。そのため、この違いにより、すぐに使えるツールを簡単に作成できることがよくあります。人間にとっては、いったん慣習に取り掛かると、覚えやすく、使いやすくなります。
ただし、この規則自体が期待どおりに機能するとは限らないことを指摘しておきます。
.hpp
それ自体が唯一の選択ではありません。なぜ.hh
か.hxx
?(とにかく、通常、ファイル名とパスに関する少なくとも1つの従来のルールが必要です。)個人的にはC ++プロジェクトで両方.h
を使用.hpp
しています。以下の理由により、私は上記の規約には従いません。
.h
github.com上のファイルの言語検出など、それを使用するツールも常に同じように動作するとは限りません。(これらのソースファイルがより良いメタデータになるようにシバンのようなコメントに何かがあるかもしれませんが、それはファイル名のような従来のものでもないので、一般的に信頼性もありません。)私は通常.hpp
C ++ヘッダーを使用しており、ヘッダーはテンプレートライブラリなど、ヘッダーのみの方法で使用(維持)する必要があります。の他のヘッダーの.h
場合、対応する.cpp
ファイルが実装として存在するか、C ++以外のヘッダーです。後者は、人間(または、必要に応じてメタデータが明示的に埋め込まれたツール)によってヘッダーの内容を区別するのは簡単です。
ソースファイルの拡張子は、ビルドシステムにとって意味がある場合があります。たとえば、makefileに.cpp
や.c
ファイルのルールがある場合や、コンパイラ(Microsoftなどcl.exe
)が拡張子に応じてファイルをCまたはC ++としてコンパイルする場合があります。
#include
ディレクティブにファイル名全体を提供する必要があるため、ヘッダーファイルの拡張子は関係ありません。.c
ファイルは単なるテキストインクルードなので、必要に応じてファイルを別のソースファイルに含めることができます。コンパイラには、これを明確にする前処理された出力をダンプするオプションがある場合があります(Microsoft:/P
ファイル/E
への前処理、への前処理stdout
、ディレクティブの/EP
省略#line
、/C
コメントの保持)。
.hpp
C ++環境にのみ関連するファイル、つまり、Cでコンパイルされない機能を使用するファイルに使用することを選択できます。
特定の拡張機能に利点はありませんが、それ以外の拡張機能は、ユーザー、コンパイラ、ツールによって異なる意味を持つ場合があります。 header.h
有効なヘッダーです。 header.hpp
有効なヘッダーです。 header.hh
有効なヘッダーです。 header.hx
有効なヘッダーです。 h.header
有効なヘッダーです。 this.is.not.a.valid.header
拒否の有効なヘッダーです。 ihjkflajfajfklaf
有効なヘッダーです。名前がコンパイラーによって適切に解析され、ファイルシステムがそれをサポートする限り、それは有効なヘッダーであり、その拡張の唯一の利点は、そこに何を読み取るかです。
とは言っても、拡張子に基づいて正確に仮定できることは非常に有用であるため、ヘッダーファイルには、理解しやすいルールのセットを使用するのが賢明です。個人的に、私はこのようなことをすることを好みます:
.h
。あいまいさはありません。.h
、C ++との互換性のヘッダではなくCを取得しながら、.hpp
または.hh
種類のものを、または。もちろん、これは拡張機能を処理するための多くの方法の1つに過ぎず、単純に見えても、必ずしも第一印象を信頼できるとは限りません。たとえば.h
、通常のヘッダー、および.tpp
テンプレートクラスのメンバー関数の定義のみを含むヘッダーに、メンバー関数.h
を定義するファイルを含むテンプレートクラスを.tpp
定義するファイル(.h
ヘッダーに直接両方の関数宣言と定義)。別の例として、あいまいさの可能性がない場合でも、多くの人は常にヘッダーの言語を拡張に反映します。それらに、.h
常にCヘッダーと.hpp
(または.hh
、または.hxx
など)は常にC ++ヘッダーです。また.h
、「ソースファイルに関連付けられたヘッダー」や.hpp
「すべての関数がインラインで定義されたヘッダー」に使用する人もいます。
これを考慮すると、主な利点は、一貫して同じスタイルでヘッダーに名前を付け、コードを調べている人にそのスタイルがすぐにわかるようになることです。このように、通常のコーディングスタイルに精通している人なら誰でも、特定の拡張機能の意味をざっと一目で判断できます。