web-dev-qa-db-ja.com

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

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

*.hppより*.hを使用することの長所と短所は何ですか?

476
Mark Ingram

CとC++ヘッダーの命名が異なる理由はいくつかあります。

  • 自動コードフォーマット、CおよびC++コードのフォーマットについては、異なるガイドラインがあるかもしれません。ヘッダが拡張子で区切られている場合は、適切なフォーマットを自動的に適用するようにエディタを設定できます。
  • 命名、私はC言語で書かれたライブラリがあるプロジェクトに取り組んでいて、それからラッパーはC++で実装されていました。通常、ヘッダーの名前はFeature.hとFeature.hppのように似ているため、区別するのは簡単でした。
  • あなたのプロジェクトにはC++で書かれたより適切なバージョンがあるかもしれませんが、Cバージョンを使っています(上記の点を見てください)。ヘッダがそれらが実装されている言語にちなんで命名されている場合、あなたは簡単に全てのCヘッダを見つけてC++バージョンをチェックすることができます。

覚えておいて、CはではないC++であり、自分がしていることが分からない限り、混ぜ合わせて一致させるのは非常に危険です。あなたの情報源に適切な名前をつけることはあなたが言語を区別するのに役立ちます。

465
David Holm

私は、どのヘッダーがC++ヘッダーであるのか、そしてどのヘッダーがCヘッダーであるのかをユーザーに区別させたいので、.hppを使用します。

これは、あなたのプロジェクトが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
210
paercebal

私はいつも.hppヘッダーを一種の.hおよび.cppファイルの一種のportmanteauであると考えていました...実装の詳細も含むヘッダー。

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

46
Perculator

どの拡張子を使用してもかまいません。どちらでも構いません。

Cには*.hを、C++には*.hppを使います。

26
Burkhard

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

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

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

他のテンプレートライブラリの中には、Cヘッダーに.hを、C++に.hppを使うなど、別の規則を使うものがあります。良い例は、boostライブラリでしょう。

Boost FAQからの引用

ファイル拡張子は、ファイルの「種類」を人間とコンピュータプログラムの両方に伝えます。拡張子「.h」はCヘッダーファイルに使用されるため、C++ヘッダーファイルについて間違ったことを伝えます。拡張子なしを使用すると、何も通知されず、ファイルの内容を検査してタイプを判断します。 '.hpp'を使用すると、C++ヘッダーファイルとして明確に識別され、実際にはうまく機能します。 (Rainer Deyke)

21
ProgramCpp

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

その理由は私が私の主なエディタとしてemacsを使っていて、*.hファイルをロードすると自動的にcモードに入り、*.hppファイルを読み込むと自動的にc ++モードに入るからです。

それとは別に、私は*.hより*.hppを選ぶ、またはその逆の理由はありません。

10
Serge

私は、これと同じ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++が内部プロセスを最適化するため、あるいは単に(おそらくそれらに対してさえも)新しい命名規則を発明するためにこのアイデアを思いつきました。

しかし、それは言語の一部ではありません。

そしてそれをこのように使うことを決心する時はいつでも。彼が一番気に入っているからか、ワークフローのアプリケーションによって必要とされているからだろうか。2 言語の要件です。したがって、「ppはC++で使用されるためです」と言う人はだれでも、言語定義に関しては間違っています。

C++では、前の段落に関するすべてのことが許可されています。そして、委員会が使用することを提案しているものがあれば、それは.hを使用しています。これは、ISO文書のすべての例で使用されている拡張子です。

結論:

.hの代わりに.hppを使う必要性を見たり感じたりしなければ、気にする必要はありません。どちらも標準に関して同じ品質の有効なヘッダー名を形成するためです。したがって、_ .hまたは.hppを使用することを要求するものは、標準の追加の制限事項であり、互いに一致しない他の追加の制限事項と矛盾する可能性もあります。しかし、OPは追加の言語制限について言及していないので、これが質問に対する唯一の正しい承認された答えです。

"*。hまたは* .hpp(クラス定義の場合)"は次のとおりです。

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


1私の知っていることから、どうやらそれはその.hpp拡張を思い付いた後押しフレームワークです。

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

8
dhein

私は、それがCヘッダファイルではなくC++ヘッダであることをエディタと他のプログラマの両方に明らかにするためにC++のための.hppを好む。

6
JohnMcG

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

拡張子が.hppのヘッダーファイルを用意しても、同じ論理的な流れはありません。

6
Dynite

あなたはあなたのインクルードを好きなように呼ぶことができます。

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

Cで作業して.hを使用する場合、およびC++で作業して.hppを使用する場合はお勧めです。

それは結局単なる慣習です。

6
slashmais

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

5
camh

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

ですから、C++ヘッダーファイルを書いているときは、常に.hを使います。

5
Roddy

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

私が開発するライブラリの大部分はテンプレートベースであり、したがってヘッダのみである必要があります、しかしアプリケーションを書くとき、私は宣言を実装から切り離して、そして.hと.cppファイルで終わる傾向があります

4
Enzo

Bjarne StroustrupとHerb Sutterは、次の場所にあるC++コアガイドラインにこの質問に対する声明を掲載しています。 https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#S- source は、標準の拡張機能(C++ 11、C++ 14など)における最新の変更も参照しています。

SF.1:あなたのYプロジェクトがすでに他の規約に従わない場合は、コードファイルには.cpp接尾辞を、インターフェイスファイルには.h接尾辞を使う

それは長年の約束です。しかし、一貫性がより重要であるので、あなたのプロジェクトが何か他のものを使っているなら、それに従ってください。注意

この慣習は、一般的な使用パターンを反映しています。C++とCの両方としてコンパイルする場合、ヘッダーはCと共有されることが多く、通常は.hを使用します。一方、実装ファイルはCと共有されることはめったにないため、通常は.cファイルと区別する必要があるため、通常はすべてのC++実装ファイルに別の名前(.cppなど)を付けることをお勧めします。

.hと.cppという特定の名前は必須ではなく(デフォルトとして推奨されています)、他の名前が広く使用されています。例は、.hh、.C、および.cxxです。そのような名前を同等に使用してください。このドキュメントでは、実際の拡張子が異なる場合でも、ヘッダーファイルと実装ファイルの省略形として.hと.cpp>を参照します。

あなたのIDE(あなたが使う場合)は、十分な意見について強い意見を持っているかもしれません。

Boostのような一般的なライブラリを使用しているのであれば、一貫性はすでに破られているので、.hppを使用するほうがよいので、この規約の大ファンではない.

4
ruuns

幸い、それは簡単です。

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

3
Nykal

私は.hを使用しています。マイクロソフトが使用しているもので、コードジェネレータが作成したものです。穀物に反対する必要はありません。

2
Mark Ransom

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

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

1
user1949346

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

(boostなどによる)通常の使用では、.hppは特にC++ヘッダである。一方、.hはC++以外のヘッダー専用(主にC)です。自明ではない場合が多いため、コンテンツの言語を正確に検出するのは一般的に困難です。したがって、この違いにより、すぐに使えるツールを簡単に作成できるようになります。人間にとっては、一度慣例に慣れれば、覚えやすく使いやすいということもあります。

しかし、期待通り、規約自体が必ずしもうまくいくとは限らないことを指摘します。

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

私は自分のC++プロジェクトで.h.hppの両方を個人的に使用しています。私は上記の慣習には従いません。

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

私は通常C++ヘッダに.hppを使います、そしてヘッダはheader-onlyのように使われるべきです(維持される)。テンプレートライブラリとして。 .h内の他のヘッダーについては、対応する.cppファイルが実装として存在するか、またはC++以外のヘッダーです。後者は、人間が(あるいは必要なら明示的に埋め込まれたメタデータを持つツールで)ヘッダの内容を区別するのは簡単です。

1
FrankHB

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

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

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

0
Mike Dimmick

特定の拡張機能には、ユーザー、コンパイラ、および/またはツールにとって異なる意味を持つ可能性があることを除いて、利点はありません。 header.hは有効なヘッダーです。 header.hppは有効なヘッダーです。 header.hhは有効なヘッダーです。 header.hxは有効なヘッダーです。 h.headerは有効なヘッダーです。 this.is.not.a.valid.headerは、拒否の有効なヘッダーです。 ihjkflajfajfklafは有効なヘッダーです。コンパイラが名前を適切に解析でき、ファイルシステムがそれをサポートしている限り、それは有効なヘッダーであり、拡張子の唯一の利点は、読み込むものです。

そうは言っても、拡張子に基づいて正確に仮定できるのはvery便利なので、ヘッダーファイルにわかりやすいルールセットを使用するのが賢明です。個人的に、私はこのようなことをすることを好みます:

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

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

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

0
Justin Time