私はいつもクラス定義に*.h
ファイルを使っていましたが、ブーストライブラリのコードを読んだ後、それらはすべて*.hpp
を使っていることに気づきました。私はいつもそのファイル拡張子に嫌悪感を抱いていました、私は主に私がそれに慣れていないからだと思います。
*.hpp
より*.h
を使用することの長所と短所は何ですか?
CとC++ヘッダーの命名が異なる理由はいくつかあります。
覚えておいて、CはではないC++であり、自分がしていることが分からない限り、混ぜ合わせて一致させるのは非常に危険です。あなたの情報源に適切な名前をつけることはあなたが言語を区別するのに役立ちます。
私は、どのヘッダーがC++ヘッダーであるのか、そしてどのヘッダーがCヘッダーであるのかをユーザーに区別させたいので、.hppを使用します。
これは、あなたのプロジェクトが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
ファイルの一種のportmanteauであると考えていました...実装の詳細も含むヘッダー。
通常、.hpp
を拡張子として見た(そして使用した)場合、対応する.cpp
ファイルはありません。他の人が言っているように、これは厳格で速いルールではありません。ちょうど.hpp
ファイルを使用する傾向があるだけです。
どの拡張子を使用してもかまいません。どちらでも構いません。
Cには*.h
を、C++には*.hpp
を使います。
EDIT[Dan Nissenbaumからの提案を追加]:
1つの規約では、プロトタイプがヘッダー自体に定義されているときに.hppファイルが使用されます。コンパイラはテンプレートのインスタンス生成時にのみ各タイプのコードを生成するため、ヘッダーでのそのような定義はテンプレートの場合に役立ちます。したがって、それらがヘッダーファイルで定義されていない場合、それらの定義は他のコンパイル単位からリンク時に解決されません。プロジェクトがテンプレートを多用するC++のみのプロジェクトの場合は、この規則が役立つ場合があります。
この規約に準拠する特定のテンプレートライブラリは、対応する.cppファイルがないことを示すために、.hpp拡張子を持つヘッダーを提供します。
他のテンプレートライブラリの中には、Cヘッダーに.hを、C++に.hppを使うなど、別の規則を使うものがあります。良い例は、boostライブラリでしょう。
Boost FAQからの引用
ファイル拡張子は、ファイルの「種類」を人間とコンピュータプログラムの両方に伝えます。拡張子「.h」はCヘッダーファイルに使用されるため、C++ヘッダーファイルについて間違ったことを伝えます。拡張子なしを使用すると、何も通知されず、ファイルの内容を検査してタイプを判断します。 '.hpp'を使用すると、C++ヘッダーファイルとして明確に識別され、実際にはうまく機能します。 (Rainer Deyke)
私は最近c ++ヘッダに*.hpp
を使い始めました。
その理由は私が私の主なエディタとしてemacsを使っていて、*.h
ファイルをロードすると自動的にcモードに入り、*.hpp
ファイルを読み込むと自動的にc ++モードに入るからです。
それとは別に、私は*.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
、またはこのトピックに関する他の記事で読んだことと同じです。
.hpp
がどこから来たのかわからない1しかし、私はいくつかの解析ツールの発明者、IDE、あるいはいくつかのC++
が内部プロセスを最適化するため、あるいは単に(おそらくそれらに対してさえも)新しい命名規則を発明するためにこのアイデアを思いつきました。
しかし、それは言語の一部ではありません。
そしてそれをこのように使うことを決心する時はいつでも。彼が一番気に入っているからか、ワークフローのアプリケーションによって必要とされているからだろうか。2 言語の要件です。したがって、「ppはC++で使用されるためです」と言う人はだれでも、言語定義に関しては間違っています。
C++では、前の段落に関するすべてのことが許可されています。そして、委員会が使用することを提案しているものがあれば、それは.h
を使用しています。これは、ISO文書のすべての例で使用されている拡張子です。
結論:
.h
の代わりに.hpp
を使う必要性を見たり感じたりしなければ、気にする必要はありません。どちらも標準に関して同じ品質の有効なヘッダー名を形成するためです。したがって、に_ .h
または.hpp
を使用することを要求するものは、標準の追加の制限事項であり、互いに一致しない他の追加の制限事項と矛盾する可能性もあります。しかし、OPは追加の言語制限について言及していないので、これが質問に対する唯一の正しい承認された答えです。
"*。hまたは* .hpp(クラス定義の場合)"は次のとおりです。
外部からの制限がない限り、どちらも同様に正しく適用可能です。
1私の知っていることから、どうやらそれはその.hpp
拡張を思い付いた後押しフレームワークです。
2もちろん、将来のいくつかのバージョンで何がもたらされるのかはわかりません。
私は、それがCヘッダファイルではなくC++ヘッダであることをエディタと他のプログラマの両方に明らかにするためにC++のための.hppを好む。
C++( "C Plus Plus")は.cppとして意味があります。
拡張子が.hppのヘッダーファイルを用意しても、同じ論理的な流れはありません。
あなたはあなたのインクルードを好きなように呼ぶことができます。
そのフルネームを#include
に指定するだけです。
Cで作業して.h
を使用する場合、およびC++で作業して.hpp
を使用する場合はお勧めです。
それは結局単なる慣習です。
90年代初頭の私の仕事の1つでは、ソースファイルとヘッダーファイルにそれぞれ.ccと.hhを使用しました。私はまだすべての選択肢よりもそれを好む、それはおそらくタイプするのが最も簡単だからである。
Codegear C++ Builderは、Delphiソースファイルから自動的に生成されたヘッダーファイルに.hppを使用し、「独自の」ヘッダーファイルに.hファイルを使用します。
ですから、C++ヘッダーファイルを書いているときは、常に.hを使います。
ここですでに述べたように、テンプレートクラス/関数を使用するヘッダーのみのライブラリには.hppを使用することをお勧めします。 .cppソースファイルまたは共有ライブラリまたは静的ライブラリを伴うヘッダーファイルには.hを使用することを好みます。
私が開発するライブラリの大部分はテンプレートベースであり、したがってヘッダのみである必要があります、しかしアプリケーションを書くとき、私は宣言を実装から切り離して、そして.hと.cppファイルで終わる傾向があります
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を使用するほうがよいので、この規約の大ファンではない.
幸い、それは簡単です。
C++を使用している場合は.hpp拡張子を使用し、Cには.hを使用するか、CとC++を混在させる必要があります。
私は.hを使用しています。マイクロソフトが使用しているもので、コードジェネレータが作成したものです。穀物に反対する必要はありません。
「Bjarne StroustrupによるC++プログラミング言語、第3版」では、nº1必読のC++本で、彼は* .hを使用しています。そのため、ベストプラクティスは* .hを使用することです。
ただし、*。hppも問題ありません。
ツールと人間が何かを区別するのは簡単です。それでおしまい。
(boostなどによる)通常の使用では、.hpp
は特にC++ヘッダである。一方、.h
はC++以外のヘッダー専用(主にC)です。自明ではない場合が多いため、コンテンツの言語を正確に検出するのは一般的に困難です。したがって、この違いにより、すぐに使えるツールを簡単に作成できるようになります。人間にとっては、一度慣例に慣れれば、覚えやすく使いやすいということもあります。
しかし、期待通り、規約自体が必ずしもうまくいくとは限らないことを指摘します。
.hpp
自体が唯一の選択ではありません。 .hh
や.hxx
ではないのはなぜですか? (とにかく、あなたは通常少なくとも1つのファイル名とパスに関する慣習的な規則を必要とします。)私は自分のC++プロジェクトで.h
と.hpp
の両方を個人的に使用しています。私は上記の慣習には従いません。
.h
ファイルの言語検出( Shebang のような、より良いメタデータになるためのコメントがあるかもしれませんが、ファイル名のように慣習的ではないため、信頼性も高くありません。一般的な。)私は通常C++ヘッダに.hpp
を使います、そしてヘッダはheader-onlyのように使われるべきです(維持される)。テンプレートライブラリとして。 .h
内の他のヘッダーについては、対応する.cpp
ファイルが実装として存在するか、またはC++以外のヘッダーです。後者は、人間が(あるいは必要なら明示的に埋め込まれたメタデータを持つツールで)ヘッダの内容を区別するのは簡単です。
ソースファイルの拡張子はビルドシステムにとって意味があるかもしれません。たとえば、.cpp
または.c
ファイルに対してmakefileにルールがある場合、またはコンパイラ(Microsoft cl.exe
など)によってファイルがCまたはC++としてコンパイルされる場合があります。拡張。
ファイル名全体を#include
ディレクティブに指定する必要があるため、ヘッダーファイルの拡張子は関係ありません。 .c
ファイルは、必要に応じて別のソースファイルに含めることができます。これは単なるテキストのインクルードだからです。あなたのコンパイラはこれを明確にする前処理された出力をダンプするオプションを持っているかもしれません(Microsoft:ファイルへの前処理への/P
、stdout
への前処理への/E
、/EP
ディレクティブを除外する#line
、コメントを保持する/C
)
C++環境にのみ関連するファイル、つまりCでコンパイルされない機能を使用するファイルには、.hpp
を使用することを選択できます。
特定の拡張機能には、ユーザー、コンパイラ、および/またはツールにとって異なる意味を持つ可能性があることを除いて、利点はありません。 header.h
は有効なヘッダーです。 header.hpp
は有効なヘッダーです。 header.hh
は有効なヘッダーです。 header.hx
は有効なヘッダーです。 h.header
は有効なヘッダーです。 this.is.not.a.valid.header
は、拒否の有効なヘッダーです。 ihjkflajfajfklaf
は有効なヘッダーです。コンパイラが名前を適切に解析でき、ファイルシステムがそれをサポートしている限り、それは有効なヘッダーであり、拡張子の唯一の利点は、読み込むものです。
そうは言っても、拡張子に基づいて正確に仮定できるのはvery便利なので、ヘッダーファイルにわかりやすいルールセットを使用するのが賢明です。個人的に、私はこのようなことをすることを好みます:
.h
を使用します。あいまいさはありません。.h
を取得し、C++と互換性があり、C以外のヘッダーは.hpp
または.hh
などを取得します。これは、もちろん、拡張機能を処理するmanyの方法の1つにすぎず、たとえ簡単に思えても、必ずしも第一印象を信頼することはできません。たとえば、通常のヘッダーに.h
を使用し、テンプレートクラスのメンバー関数の定義のみを含むヘッダーに.tpp
を使用し、テンプレートクラスを定義する.h
ファイル(関数宣言と定義の両方を直接含む.tpp
ヘッダーの代わりに)メンバー関数を定義する.h
ファイル。別の例として、あいまいさの可能性がない場合でも、非常に多くの人々がヘッダーの言語をその拡張に常に反映しています。 .h
は常にCヘッダーであり、.hpp
(または.hh
、または.hxx
など)は常にC++ヘッダーです。さらに、「ソースファイルに関連付けられたヘッダー」に.h
を使用し、「インラインで定義されたすべての関数を含むヘッダー」に.hpp
を使用する人もいます。
これを考慮すると、主な利点は、一貫して同じスタイルでヘッダーに名前を付け、そのスタイルをコードを調べている人にすぐに明らかにすることです。このようにして、通常のコーディングスタイルに精通している人なら、特定の拡張機能の意味を大まかに一目で判断できます。