質問
クラス定義には常に*.h
ファイルを使用していましたが、ブーストライブラリコードを読んだ後、すべてが*.hpp
を使用していることに気付きました。私はいつもそのファイル拡張子に嫌悪感を抱いてきました。主に私はそれに慣れていないからだと思います。
<=>よりも<=>を使用する利点と欠点は何ですか?
解決
CヘッダーとC ++ヘッダーの命名が異なる2つの理由を次に示します。
- コードの自動書式設定では、CおよびC ++コードの書式設定に関するガイドラインが異なる場合があります。ヘッダーが拡張子で区切られている場合、適切なフォーマットを自動的に適用するようにエディターを設定できます
- ネーミング、私はCで書かれたライブラリがあり、ラッパーがC ++で実装されていたプロジェクトに取り組んできました。ヘッダーは通常似た名前、つまりFeature.hとFeature.hppを持っているため、区別するのは簡単でした。
- 含まれるのは、C ++で書かれたより適切なバージョンがプロジェクトにあるかもしれませんが、Cバージョンを使用していることです(上記のポイントを参照)。ヘッダーに実装されている言語にちなんで名前が付けられている場合、すべてのCヘッダーを簡単に見つけてC ++バージョンを確認できます。
CはC ++であるではないことを忘れないでください。何をしているのかわからない限り、組み合わせて使うのは非常に危険です。ソースに適切な名前を付けると、言語を区別するのに役立ちます。
他のヒント
.hppを使用する理由は、ユーザーにどのヘッダーがC ++ヘッダーであり、どのヘッダーがCヘッダーであるかを区別してほしいからです。
これは、プロジェクトでCモジュールとC ++モジュールの両方を使用している場合に重要になる可能性があります。他の人が前に説明したように、非常に慎重に行う必要があり、<!> quot; contract <!> quot;拡張機能を介して提供します
.hpp:C ++ヘッダー
(または.hxx、または.hh、その他)
このヘッダーはC ++専用です。
Cモジュールを使用している場合は、含めないでください。 Cフレンドリーにする努力がなされていないので、それは気に入らないでしょう(関数のオーバーロード、名前空間などのように、あまりにも多くが失われます)。
.h:C / C ++互換または純粋なCヘッダー
このヘッダーは、CソースとC ++ソースの両方に直接または間接的に含めることができます。
__cplusplus
マクロによって保護されて、直接含めることができます:
- つまり、C ++の観点からすると、C互換コードは
extern "C"
として定義されます。 - Cの観点からは、すべてのCコードは明確に表示されますが、C ++コードは非表示になります(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
または、<=>宣言で囲む対応する.hppヘッダーによって間接的に含めることができます。
例:
#ifndef MY_HEADER_HPP
#define MY_HEADER_HPP
extern "C"
{
#include "my_header.h"
}
#endif // MY_HEADER_HPP
and:
#ifndef MY_HEADER_H
#define MY_HEADER_H
void myCFunction() ;
#endif // MY_HEADER_H
.hpp
ヘッダーは、常に.h
および.cpp
ファイルの一種であると考えていました...実装の詳細も含まれるヘッダーです。
通常、拡張機能として<=>を見た(そして使用した)とき、対応する<=>ファイルはありません。他の人が言ったように、これは厳格なルールではなく、私が<=>ファイルを使用する傾向があります。
使用する拡張機能は関係ありません。どちらでも構いません。
Cには*.h
を使用し、C ++には*.hpp
を使用します。
編集 [ダンニッセンバウムからの提案を追加]:
1つの規則により、.hppファイルは、ヘッダー自体でプロトタイプが定義されるときに使用されます。コンパイラはテンプレートのインスタンス化でのみ各タイプのコードを生成するため、ヘッダーのこのような定義はテンプレートの場合に役立ちます。したがって、ヘッダーファイルで定義されていない場合、それらの定義はリンク時に他のコンパイルユニットから解決されません。プロジェクトがテンプレートを多用するC ++のみのプロジェクトである場合、この規則が役立つ場合があります。
この規則に従う特定のテンプレートライブラリは、対応する.cppファイルがないことを示すために、ヘッダーに.hpp拡張子を提供します。
他のテンプレートライブラリの中には、Cヘッダーに.hを、C ++に.hppを使用するなど、別の規則を使用するものがあります。良い例は、ブーストライブラリです。
Boost FAQからの引用
ファイル拡張子は、<!> quot; type <!> quot;両方の人間へのファイルの とコンピュータープログラムに。 「.h」拡張子はCヘッダーに使用されます ファイル、したがって、C ++ヘッダーについて間違ったものを伝えます ファイル。拡張機能を使用しないと何も伝達されず、検査が強制されます タイプを決定するファイルの内容の。 「.hpp」を明確に使用する これをC ++ヘッダーファイルとして識別し、実際の運用でうまく機能します。 (Rainer Deyke)
最近、C ++ヘッダーに*.hpp
の使用を開始しました。
その理由は、emacsをプライマリエディタとして使用し、*.h
ファイルをロードするとc-modeに、<=>ファイルをロードするとc ++-modeに自動的に移行するためです。
その事実は別として、<=>よりも<=>を選択する、またはその逆を選択する理由はありません。
<!> quot; user1949346 <!> quot;に対するコメントにポイントを与えるために、これをリマインダーとして回答しています。この同じOPに答えます。
多くの人がすでに答えています:どちらの方法でも構いません。 その後、自分の印象を強調します。
前に述べたコメントでも述べたように、私の意見では、C++
実際にそれに対する理由がない場合、ヘッダー拡張は.h
であると提案されています。
ISO / IEC文書はこのヘッダーファイルの表記法を使用しているため、.hpp
に関する言語文書でも'\n'
に一致する文字列は発生しません。
しかし、私は現在、どちらの方法でも大丈夫な理由、特にそれがそれ自体の言語の主題ではない理由を承認することを目指しています。
だからここに行きます。
<>
のドキュメント(バージョン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 "
この部分から抽出できるように、ヘッダーファイル名もソースコードで有効なものであれば何でもかまいません。 >
文字を含む場合を除き、""
に含めるかどうかに応じて、"
を含めることはできません。
または、prettyStupidIdea.>
-includeによってインクルードされる場合、.cc
を含むことはできません。
つまり、.mm
などのファイル名をサポートする環境がある場合、次のようなインクルード:
#include "prettyStupidIdea.>"
有効ですが、:
#include <prettyStupidIdea.>>
は無効になります。同じ周りの別の方法。
さらに
#include <<.<>
有効なインクルード可能なヘッダーファイル名になります。
これは<=>に準拠していても、かなり馬鹿げたアイデアでしょう、トー。
そして、だから<=>も有効です。
しかし、それは委員会が言語の決定を設計した結果ではありません!
したがって、<=>の使用について議論することは、<=>、<=>、またはこのトピックに関する他の投稿で読んだことについて行うことと同じです。
<=>が 1 の由来がわからないことを認めなければなりませんが、解析ツール、IDE、または<=>に関係する他の何かの発明者がこのアイデアを思いついたと思います。いくつかの内部プロセスを最適化するため、またはいくつかの(おそらくそれらの場合でも)新しい命名規則を考案するために。
ただし、言語の一部ではありません。
そして、この方法で使用することに決めたときはいつでも。彼がそれを一番気に入っているか、ワークフローの一部のアプリケーションがそれを必要としているからかもしれませんが、 2 は言語の要件ではありません。つまり、<!> quot; ppは、C ++ <!> quot;で使用されるためです。言語定義に関しては単に間違っています。
C ++では、前の段落を尊重するものなら何でも使用できます。 委員会が使用を提案したものがある場合、これは<=>を使用しています。これは、ISO文書のすべての例で提訴されている拡張機能であるためです。
結論:
<=>を介して<=>を使用したり、その逆を使用したりする必要性を感じない/感じない限り、気にする必要はありません。どちらも標準に関して同じ品質の有効なヘッダー名を形成するためです。したがって、<=>または<=>を使用する必要がある必要は、標準の追加の制限であり、互いに適合しない他の追加の制限と矛盾することさえあります。しかし、OPは追加の言語制限について言及していないため、これは質問に対する唯一の正しい承認可能な回答です。
<!> quot; *。hまたは* .hpp(クラス定義の場合) <!> quot;次のとおりです。
外部の制限がない限り、どちらも等しく正しく適用できます。
1 私が知っていることから、明らかに、<=>拡張を思いついたのはブーストフレームワークです。
2 もちろん、将来のバージョンで何がもたらされるかは言えません!
C ++の.hppは、エディタと他のプログラマの両方に、CヘッダーファイルではなくC ++ヘッダーであることを明確にするために好まれます。
C ++(<!> quot; C Plus Plus <!> quot;)は.cppとして意味があります
拡張子が.hppのヘッダーファイルを作成しても、同じ論理フローはありません。
インクルードは、好きなものを呼び出すことができます。
#include
でそのフルネームを指定する必要があります。
Cを使用して.h
を使用する場合、C ++を使用して.hpp
を使用する場合をお勧めします。
最終的には単なる慣習です。
Codegear C ++ Builderは、Delphiソースファイルから自動的に生成されるヘッダーファイルに.hppを使用し、<!> quot; own <!> quotに.hファイルを使用します。ヘッダーファイル。
したがって、C ++ヘッダーファイルを作成するときは、常に.hを使用します。
90年代前半の仕事の1つで、ソースファイルとヘッダーファイルにそれぞれ.ccと.hhを使用しました。おそらく最も簡単に入力できるため、私はすべての選択肢よりもそれを好んでいます。
Bjarne StroustrupとHerb SutterのC ++コアガイドラインには、この質問に対する声明があります: https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#S-source は、標準拡張(C + + 11、C ++ 14など)
SF.1:コードファイルには.cppサフィックスを使用し、インターフェイスファイルには.hを使用します Yプロジェクトはまだ別の慣習に従っていません 理由
これは長年の慣習です。しかし、一貫性がより重要なので、 あなたのプロジェクトは何か他のものを使用します。 注
この規則は、一般的な使用パターンを反映しています。ヘッダーはより頻繁に共有されます Cを使用してC ++とCの両方としてコンパイルします。通常は.hを使用し、 異なる拡張子を持つ代わりに、すべてのヘッダーに.hという名前を付ける方が簡単です Cと共有することを目的としたヘッダーのみです。一方、 実装ファイルはめったにCと共有されないため、通常は .cファイルと区別されるため、通常はすべてのC ++に名前を付けるのが最善です 実装ファイルは何か他のもの(.cppなど)。
特定の名前.hおよび.cppは必要ありません( デフォルト)およびその他の名前が広く使用されています。例は、.hh、.C、および .cxx。そのような名前を同等に使用します。このドキュメントでは、.hおよび.cpp <!> gt;を参照します。実際のヘッダーファイルと実装ファイルの省略形として 拡張子は異なる場合があります。
IDE(使用する場合)で十分な意見があるかもしれません。
boostのような人気のあるライブラリを使用している場合、一貫性がすでに失われているため、.hppを使用する必要があるため、私はこの規則の大ファンではありません。
ここですでに述べたように、テンプレートクラス/関数を使用するヘッダーのみのライブラリには.hppを使用することも好みます。 .cppソースファイルまたは共有ライブラリまたは静的ライブラリを伴うヘッダーファイルには.hを使用することを好みます。
開発するライブラリのほとんどはテンプレートベースであるため、ヘッダーのみである必要がありますが、アプリケーションを記述するときは、宣言を実装から分離し、.hおよび.cppファイルで終わる傾向があります
幸いなことに、それは簡単です。
C ++で作業している場合は.hpp拡張子を使用する必要があり、Cには.hを使用するか、CとC ++を混合する必要があります。
.hを使用するのは、それがMicrosoftが使用し、コードジェネレーターが作成するものだからです。穀物に逆らう必要はありません。
<!> quot; The C ++ Programming Language、Third Edition by Bjarne Stroustrup <!> quot;、n <!>#186; 1必読のC ++本では、*。hを使用しています。したがって、ベストプラクティスは* .hを使用することだと思います。
ただし、*。hppも問題ありません!
ツールと人間にとって何かを区別するのは簡単です。それだけです。
(ブーストなどによる)従来の使用では、.hpp
は具体的にはC ++ヘッダーです。一方、.h
は非C ++専用ヘッダー(主にC)用です。コンテンツの言語を正確に検出することは、多くの非自明なケースがあるため一般に困難です。そのため、この違いにより、すぐに使用できるツールを簡単に作成できます。人間にとっては、一度慣習を得れば、覚えやすく使いやすくなります。
ただし、予想どおり、規則自体は常に機能するとは限りません。
- 言語の仕様による強制ではない。CもC ++もありません。慣習に従わないプロジェクトが多数存在します。それらをマージ(混合)する必要があると、面倒になる可能性があります。
-
.hh
自体が唯一の選択肢ではありません。なぜ.hxx
または.cpp
ではないのですか? (とにかく、通常、ファイル名とパスに関する従来のルールが少なくとも1つ必要です。)
私は個人的にC ++プロジェクトで<=>と<=>の両方を使用しています。次の理由により、上記の規則に従わない:
- プロジェクトの各部分で使用される言語は明示的に文書化されています。同じモジュール(ディレクトリ)でCとC ++を混在させることはできません。このルールに準拠するには、すべてのサードパーティライブラリが必要です。
- プロジェクトで使用されている適合言語仕様と許可されている言語方言も文書化されています。 (実際には、標準機能とバグ修正のソース(これはエラーが発生しやすく、テストのコスト(例:コンパイラーの互換性)が大きい(複雑で時間がかかる)ため、これは使用言語を区別するよりもいくらか重要です、特に、すでにほぼ純粋な C ++になっているプロジェクトでは。ファイル名はこれを処理するには弱すぎます。
- 同じC ++方言であっても、違いに適したより重要なプロパティがあるかもしれません。たとえば、以下の規則を参照してください。
- ファイル名は、本質的に脆弱なメタデータです。慣習違反は簡単に検出できません。コンテンツを安定して扱うためには、ツールは最終的に名前だけに依存するべきではありません。拡張機能の違いはヒントにすぎません。また、それを使用するツールが常に同じ動作をすることも期待されるべきではありません。 github.comの<=>ファイルの言語検出。 (これらのソースファイルがより良いメタデータであるために、 shebang のようなコメントがあるかもしれません。しかし、ファイル名のように従来のものではないため、一般的に信頼性も低くなります。)
通常、C ++ヘッダーで<=>を使用し、ヘッダーは header-only の方法で使用(保守)する必要があります。テンプレートライブラリとして。 <=>内の他のヘッダーについては、対応する<=>ファイルが実装として存在するか、C ++以外のヘッダーです。後者は、人間(または、必要に応じて明示的な埋め込みメタデータを持つツール)がヘッダーのコンテンツを区別するのは簡単です。
ソースファイルの拡張子は、ビルドシステムにとって意味がある場合があります。たとえば、メイクファイルに.cpp
または.c
ファイルのルールがある場合や、コンパイラ(たとえばMicrosoft cl.exe
)がコンパイルする場合があります拡張子に応じて、CまたはC ++としてファイル。
#include
ディレクティブにファイル名全体を指定する必要があるため、ヘッダーファイルの拡張子は関係ありません。必要に応じて、別のソースファイルに/P
ファイルを含めることができます。これは単なるテキストのインクルードであるためです。コンパイラには、これを明確にする前処理された出力をダンプするオプションがある場合があります(Microsoft:/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
を使用します。あいまいさはありません。 - 一部のヘッダーが複数の言語と互換性があり、他のヘッダーが単一の言語とのみ互換性がある場合、拡張機能はヘッダーが互換性のある最も制限的な言語に基づいています。 Cまたは両方のC <!> ampと互換性のあるヘッダー。 C ++は
.hpp
を取得し、C ++と互換性があるがCは互換性のないヘッダーは.hh
または.tpp
などを取得します。
これは、もちろん、拡張機能を処理する多くの方法の1つにすぎず、たとえ簡単に思えても、第一印象を必ずしも信頼できるとは限りません。たとえば、通常のヘッダーに.hxx
を使用し、テンプレートクラスメンバー関数の定義のみを含むヘッダーに<=>を使用し、<=>ファイルを定義する<=>ファイルを含むテンプレートクラスを定義するという記述を見てきましたそれらのメンバー関数(関数宣言と定義の両方を直接含む<=>ヘッダーの代わりに)。別の例として、あいまいさの可能性がない場合でも、非常に多くの人々がヘッダーの言語をその拡張に常に反映しています。彼らにとって、<=>は常にCヘッダーであり、<=>(または<=>、または<=>など)は常にC ++ヘッダーです。さらに、一部の人々は、ソースファイルに関連付けられた<!> quot;ヘッダーに<=>を使用しています。 <!> quot;ヘッダーのすべての関数がインライン<!> quot;に定義されている<=>。
これを考慮すると、主な利点は、一貫して同じスタイルでヘッダーに名前を付け、コードを調べている人にそのスタイルをすぐに明らかにすることです。このようにして、通常のコーディングスタイルに精通している人であれば、特定の拡張機能の意味を簡単に一目で判断できます。