クラス定義の* .hまたは* .hpp


554

私は常に*.hクラス定義にファイルを使用してきましたが、いくつかのboostライブラリコードを読んだ後、すべてがを使用していることに気付きました*.hpp。私はいつもそのファイル拡張子に嫌悪感を抱いてきました、私はそれに慣れていないことが主な理由だと思います。

*.hppover を使用する利点と欠点は何*.hですか?

回答:


528

CヘッダーとC ++ヘッダーの名前が異なる理由は次のとおりです。

  • 自動コードフォーマットでは、CおよびC ++コードのフォーマットについて異なるガイドラインがある場合があります。ヘッダーが拡張子で区切られている場合は、適切なフォーマットを自動的に適用するようにエディターを設定できます
  • ネーミング、私はCで書かれたライブラリがあり、ラッパーがC ++で実装されているプロジェクトに携わってきました。ヘッダーは通常、似た名前、つまりFeature.hとFeature.hppを持っているため、簡単に区別できます。
  • 含まれています。おそらく、プロジェクトにはC ++で記述されたより適切なバージョンがありますが、Cバージョンを使用しています(上記のポイントを参照)。ヘッダーが実装されている言語に基づいてヘッダーに名前が付けられている場合、すべてのCヘッダーを簡単に見つけて、C ++バージョンを確認できます。

CはC ++ではないので、自分が何をしているのかを知らない限り、混ぜて一致させるのは非常に危険です。ソースに適切な名前を付けると、言語を区別するのに役立ちます。


234

.hppを使用するのは、ユーザーにC ++ヘッダーとCヘッダーを区別するためです。

これは、プロジェクトでCモジュールとC ++モジュールの両方を使用している場合に重要になる可能性があります。私の前に説明した他の人と同様に、非常に注意深く行う必要があります。

.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

または、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

3
これは多くのC ++プロジェクトでは非常に珍しいことです。.hファイルは、Cっぽくないものに使用されます。
einpoklum 2016年

4
@einpoklum:もちろんです。しかし、私は "Monkey See Monkey Do"の振る舞いを避けようとしています。現在のケースでは、両方の拡張機能(および他の拡張機能)が利用できるので、実際にそれらを数えるようにします。クライアントと共有するコードとのこの契約は非常に便利です。誰でも(つまり、何百人もの開発者)は、Cコンパイラを使用してクライアントが「.H」ファイルを使用することを知っているので、そこに何ができるかについて間違いはありません。ない。そして、すべての人(クライアントを含む)は、「。HPP」ファイルがCフレンドリーになることは決してないことを知っています。誰もが勝つ。
paercebal 2016年

4
@paercebal、それであなたは.hの代わりに.H.hppより.HPPを提案しているのですか?
Geof Sawaya

6
@GeofSawaya:いいえ、ごめんなさい。それは習慣です。記事を書くときは、大文字の拡張子を使用して、「。HPPファイル」のようにファイルを種類で区別しています。しかし、私のハードディスクにある実際のファイルの拡張子は、「MyClass.hpp」や「module.hpp」のように、たとえ小文字であっても、常に小文字です
paercebal

4
ありがとう、@ paercebal。私は夢中になっていた
Geof Sawaya

48

私は常に.hppヘッダーを一種のportmanteau .h.cppファイルだと考えていました...実装の詳細も含むヘッダーです。

通常.hpp、拡張子として見た(そして使用した)場合、対応する.cppファイルはありません。他の人が言ったように、これは難しくて速い規則ではありません、ちょうど私が.hppファイルを使う傾向があるだけです。


31

使用する拡張子は関係ありません。どちらでもかまいません。

*.hCと*.hppC ++ に使用しています。


23

編集 [Dan Nissenbaumからの提案を追加]:

1つの規則では、プロトタイプがヘッダー自体で定義されるときに.hppファイルが使用されます。コンパイラーはテンプレートのインスタンス化時にのみ各タイプのコードを生成するため、このようなヘッダーの定義はテンプレートの場合に役立ちます。したがって、それらがヘッダーファイルで定義されていない場合、それらの定義はリンク時に他のコンパイルユニットから解決されません。プロジェクトが、テンプレートを多用するC ++のみのプロジェクトである場合、この規則が役立ちます。

この規則に準拠している特定のテンプレートライブラリは、ヘッダーに.hpp拡張子を付けて、対応する.cppファイルがないことを示します。

別の規則は、Cヘッダーに.hを使用し、C ++に.hppを使用することです。良い例は、boostライブラリです。

Boost FAQからの引用、

ファイル拡張子は、人間とコンピュータプログラムの両方にファイルの「タイプ」を伝えます。'.h'拡張子はCヘッダーファイルに使用されるため、C ++ヘッダーファイルについて誤った情報を伝えます。拡張子を使用しないと、何も通信せず、ファイルの内容を検査してタイプを判別します。'.hpp'を使用すると、それがC ++ヘッダーファイルとして明確に識別され、実際の作業でうまく機能します。(レイナー・デイケ)


コードの生成やリンクに関しては、ファイルが.hでも.hppでも違いはありません。
イングラムのマーク

それは単なる慣習の問題ではないですか?C ++ stdライブラリは、すべてのヘッダーを拡張なしで提供します。「.hpp」の使用は、プロトタイプが同じファイルで定義されており、対応する.cppファイルがないことを示しています。
ProgramCpp

5
この答えは便利だと思いますが、「言語の規則ではなく、慣例による」という非常に単純で重要なフレーズが欠けていることは例外です(どこかで)。
Dan Nissenbaum、2014

13

私は最近使い始めました *.hpp c ++ヘッダーのをました。

その理由は、私はプライマリエディタとしてemacsを使用しており、*.hファイルをロードすると自動的にcモードになり、ファイルをロードするとc ++モードになり*.hppます。

その事実を除けば、私が選択すること*.h*.hppまたはその逆を選択することには十分な理由がありません。


7
個人的には、CヘッダーでもC ++の強調表示は良い考えだと思います。私は誰かがC ++からCヘッダーを含めたいという状況の両端にいますが、それはパラメーター名としてC ++キーワードを使用しています...
Steve Jessop

12

私は、これと同じ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 ++では、前の段落を尊重するものはすべて許可されます。そして、委員会が使用することを提案したものがあれば、それは.hISOドキュメントのすべての例で訴えられた拡張であるため、それを使用しています。

結論:

.hover を使用し.hppたり、その逆を使用したりする必要がまったくない、または感じない限り、気にする必要はありません。どちらも標準に関して同じ品質の有効なヘッダー名を形成するからです。したがって、何もREQUIRES使用することができ.hたり.hppしても、他の追加の制限と矛盾することができ、相互に適合していない標準の追加の制限です。しかし、OPは追加の言語制限について言及していないため、これが質問に対する唯一の正しい承認可能な回答です

" クラス定義の* .hまたは* .hpp "は:

外部の制限が存在しない限り、どちらも同様に正しく適用可能です。


1 私が知っていることから、明らかに、その.hpp拡張機能を思いついたのはブーストフレームワークです。

2 もちろん、将来のいくつかのバージョンで何がもたらされるかは言えません!


7

CヘッダーファイルではなくC ++ヘッダーであることを両方のエディターと他のプログラマーに明確にするために、C ++の.hppを好みます。


6

C ++( "C Plus Plus")は.cppとして意味があります

ヘッダーファイルに.hpp拡張子を付けることは、同じ論理フローではありません。


6

インクルードは好きなように呼び出すことができます。

そのフルネームをで指定するだけです#include

Cを使用.hして使用する場合と、C ++を使用して使用する場合をお勧めします.hpp

結局のところ、これは単なる慣例です。


5

Codegear C ++ Builderは、Delphiソースファイルから自動的に生成されたヘッダーファイルには.hppを使用し、「独自の」ヘッダーファイルには.hファイルを使用します。

したがって、C ++ヘッダーファイルを作成するときは、常に.hを使用します。


5

90年代前半の私の仕事の1つでは、ソースファイルとヘッダーファイルにそれぞれ.ccと.hhを使用しました。おそらく入力するのが最も簡単なため、私はまだすべての選択肢よりもそれを好みます。


5

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を使用する必要があるため、私はこの規則の大ファンではありません。


4

ここで多くの人がすでに述べたように、私はまた、テンプレートクラス/関数を使用するヘッダーのみのライブラリに.hppを使用することを好みます。.cppソースファイルまたは共有または静的ライブラリを伴うヘッダーファイルには.hを使用することを好みます。

私が開発するほとんどのライブラリはテンプレートベースであるため、ヘッダーのみである必要がありますが、アプリケーションを作成するときは、宣言と実装を分離し、最終的に.hファイルと.cppファイルで終了する傾向があります


3

幸いなことに、それは簡単です。

C ++を使用している場合は.hpp拡張子を使用し、Cの場合は.hを使用するか、CとC ++を混合する必要があります。


2

.hを使用しているのは、それがMicrosoftが使用し、コードジェネレーターが作成するものだからです。穀物に逆らう必要はありません。


どこにでもあるわけではありませんが、多くの例(eq WINDDK)では.hppを使用しています
marsh-wiggle 14

13
C ++に関しては、Microsoftを「穀物」とは呼びません。
developerbmw

@ブレットそれはあなたの仕事です。そうでない場合でも、それは非常に人気のあるコンパイラです。
Mark Ransom 2014

@MarkRansom Cの使用に関するMicrosoftの歴史をより詳しく参照しました。IMOVC ++は優れたコンパイラーです。
developerbmw

1
@developerbmw個人的には、MSVCはWindowsプログラムの粒度であり、GCCは* nixプログラムの粒度です。それらは、私の知る限り、これらのプラットフォーム用の他のほとんどのコンパイラーが互換性を維持しようとする傾向があるものです。
ジャスティンタイム-モニカを2016年

1

「C ++プログラミング言語、Bjarne Stroustrupによる第3版」では、nº1必読のC ++の本で、彼は* .hを使用しています。したがって、ベストプラクティスは* .hを使用することだと思います。

ただし、*。hppも問題ありません。


1
ある人が他の人から学んだことについて他の人から学んだことについて本を書いた場合(多分同じ運で)本を入手できる可能性のある人が書いた本であるなら、それは彼らが何をしているのかということではありません。ビーイングベストプラクティス。
dhein 2016年

ただ言及するだけです。私は実際にこれに反対しました。しかし、「ISO / IEC N3690」またはその他のC ++ドラフトのいずれかが「Cjarプログラミング言語、Bjarne Stroustrupによる第3版」ではない場合、私はそれを支持したでしょう。.hpp言語自体による言及がまったくないため、これは有効なポイントでした。
dhein 2016年

9
@zaibis Bjarne StroustrupがC ++を発明したことを知っていますか?
tumtumtum 2016年

@tumtumtum:認めた、私はこれを知らなかった。しかしとにかく、その場合でも、それは委員会の文書であり、基準を維持し、それは取るべき参照です。彼が言語の発明者であったとしても、それはもはや彼の決定ではありません。したがって、これによりこの回答の価値は高まりますが、それでも正当な理由にはなりません。
dhein

1

ツールと人間が何かを区別するのは簡単です。それでおしまい。

従来の使用(ブーストなどによる)では、.hpp特にC ++ヘッダーです。一方、.h非C ++のみのヘッダー(主にC)用です。重要なケースが多数あるため、コンテンツの言語を正確に検出することは一般に困難です。そのため、この違いにより、すぐに使えるツールを簡単に作成できることがよくあります。人間にとっては、いったん慣習に取り掛かると、覚えやすく、使いやすくなります。

ただし、この規則自体が期待どおりに機能するとは限らないことを指摘しておきます。

  • 言語の仕様によって強制されることはなく、CやC ++も同様です。規約に従わない多くのプロジェクトが存在します。それらをマージする(混合する)必要があると、面倒になる可能性があります。
  • .hppそれ自体が唯一の選択ではありません。なぜ.hh.hxx?(とにかく、通常、ファイル名とパスに関する少なくとも1つの従来のルールが必要です。)

個人的にはC ++プロジェクトで両方.hを使用.hppしています。以下の理由により、私は上記の規約には従いません。

  • プロジェクトの各部分で使用される言語は明示的に文書化されています。同じモジュール(ディレクトリ)でCとC ++を混在させることはできません。このルールに準拠するには、すべてのサードパーティライブラリが必要です。
  • 準拠した言語仕様とプロジェクトで使用される許可された言語方言も文書化されています。(実際、標準機能のソースと使用されている(言語標準の)バグ修正も文書化しています。)これは、エラーが発生しやすく、テストのコスト(たとえば、コンパイラの互換性)は、特にほぼ純粋な C ++に既に含まれいるプロジェクトでは、重要(複雑で時間がかかる)になる可能性があります。ファイル名はこれを処理するには弱すぎます。
  • 同じC ++方言でも、その違いに適したより重要なプロパティがある場合があります。たとえば、以下の規則を参照してください。
  • ファイル名は本質的に壊れやすいメタデータの一部です。慣習の違反を検出することはそれほど簡単ではありません。コンテンツの処理を安定させるには、ツールは最終的に名前だけに依存するべきではありません。拡張機能の違いはヒントにすぎません。.hgithub.com上のファイルの言語検出など、それを使用するツールも常に同じように動作するとは限りません。(これらのソースファイルがより良いメタデータになるようにシバンのようなコメントに何かがあるかもしれませんが、それはファイル名のような従来のものでもないので、一般的に信頼性もありません。)

私は通常.hppC ++ヘッダーを使用しており、ヘッダーはテンプレートライブラリなど、ヘッダーのみの方法で使用(維持)する必要があります。の他のヘッダーの.h場合、対応する.cppファイルが実装として存在するか、C ++以外のヘッダーです。後者は、人間(または、必要に応じてメタデータが明示的に埋め込まれたツール)によってヘッダーの内容を区別するのは簡単です。


0

ソースファイルの拡張子は、ビルドシステムにとって意味がある場合があります。たとえば、makefileに.cpp.cファイルのルールがある場合や、コンパイラ(Microsoftなどcl.exe)が拡張子に応じてファイルをCまたはC ++としてコンパイルする場合があります。

#includeディレクティブにファイル名全体を提供する必要があるため、ヘッダーファイルの拡張子は関係ありません。.cファイルは単なるテキストインクルードなので、必要に応じてファイルを別のソースファイルに含めることができます。コンパイラには、これを明確にする前処理された出力をダンプするオプションがある場合があります(Microsoft:/Pファイル/Eへの前処理、への前処理stdout、ディレクティブの/EP省略#line/Cコメントの保持)。

.hppC ++環境にのみ関連するファイル、つまり、Cでコンパイルされない機能を使用するファイルに使用することを選択できます。


0

特定の拡張機能に利点はありませんが、それ以外の拡張機能は、ユーザー、コンパイラ、ツールによって異なる意味を持つ場合があります。 header.h有効なヘッダーです。 header.hpp有効なヘッダーです。 header.hh有効なヘッダーです。 header.hx有効なヘッダーです。 h.header有効なヘッダーです。 this.is.not.a.valid.header拒否の有効なヘッダーです。 ihjkflajfajfklaf有効なヘッダーです。名前がコンパイラーによって適切に解析され、ファイルシステムがそれをサポートする限り、それは有効なヘッダーであり、その拡張の唯一の利点は、そこに何を読み取るかです。

とは言っても、拡張子に基づいて正確に仮定できることは非常に有用であるため、ヘッダーファイルには、理解しやすいルールのセットを使用するのが賢明です。個人的に、私はこのようなことをすることを好みます:

  1. すでに確立されたガイドラインがある場合は、混乱を防ぐためにそれらに従ってください。
  2. プロジェクト内のすべてのソースファイルが同じ言語用である場合は、を使用します.h。あいまいさはありません。
  3. 一部のヘッダーが複数の言語と互換性がある一方で、他のヘッダーは単一の言語とのみ互換性がある場合、拡張機能はヘッダーが互換性のある最も制限的な言語に基づいています。Cと互換性のあるヘッダ、または有するC&C ++の両方、取得.h、C ++との互換性のヘッダではなくCを取得しながら、.hppまたは.hh種類のものを、または。

もちろん、これは拡張機能を処理するための多くの方法の1つに過ぎず、単純に見えても、必ずしも第一印象を信頼できるとは限りません。たとえば.h、通常のヘッダー、および.tppテンプレートクラスのメンバー関数の定義のみを含むヘッダーに、メンバー関数.hを定義するファイルを含むテンプレートクラスを.tpp定義するファイル(.hヘッダーに直接両方の関数宣言と定義)。別の例として、あいまいさの可能性がない場合でも、多くの人は常にヘッダーの言語を拡張に反映します。それらに、.h常にCヘッダーと.hpp(または.hh、または.hxxなど)は常にC ++ヘッダーです。また.h、「ソースファイルに関連付けられたヘッダー」や.hpp「すべての関数がインラインで定義されたヘッダー」に使用する人もいます。

これを考慮すると、主な利点は、一貫して同じスタイルでヘッダーに名前を付け、コードを調べている人にそのスタイルがすぐにわかるようになることです。このように、通常のコーディングスタイルに精通している人なら誰でも、特定の拡張機能の意味をざっと一目で判断できます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.