web-dev-qa-db-ja.com

C ++ヘッダーの順序

ヘッダー/ cppファイルでヘッダーを宣言する順序は何ですか?明らかに、後続のヘッダーで必要なものはもっと早く、クラス固有のヘッダーはヘッダースコープではなくcppスコープにある必要がありますが、順序の規則/ベストプラクティスはありますか?

34
Konrad

ヘッダーファイルには、コンパイル可能にするためにすべてのヘッダーをインクルードする必要があります。また、いくつかのヘッダーの代わりに前方宣言を使用することを忘れないでください。

ソースファイルの場合:

  • 対応するヘッダーファイル
  • 必要なプロジェクトヘッダー
  • サードパーティライブラリヘッダー
  • 標準ライブラリヘッダー
  • システムヘッダー

この順序で、ライブラリを独自にインクルードするのを忘れたヘッダーファイルを見逃すことはありません。

63
Mykola Golubyev

グッドプラクティス:すべての.hファイルには、他の何よりも先にその.hを含む.cppが必要です。これは、任意の.hファイルを最初に配置できることを証明しています。

ヘッダーに実装が必要ない場合でも、その.hファイルだけを含む.cppを作成します。

これは、あなたが好きな方法であなたの質問に答えることができることを意味します。それらをどの順序で含めるかは問題ではありません。

さらに優れたヒントについては、この本を試してください。 大規模C++ソフトウェア設計 -非常に高価なのは残念ですが、実際にはC++ソースコードレイアウトのサバイバルガイドです。

21

ヘッダーファイルでは、最初に標準ヘッダーを配置し、次に自分のヘッダーを配置する傾向があります(両方のリストはアルファベット順に並べられています)。実装ファイルでは、最初に対応するヘッダー(存在する場合)を配置し、次に標準ヘッダーとその他の依存関係ヘッダーを配置します。

マクロと#defineをうまく利用する場合を除いて、順序はほとんど重要ではありません。その場合、定義したマクロが以前に含まれていたマクロを置き換えないことを確認する必要があります(もちろん、それが必要な場合を除きます)。

この声明について

後続のヘッダーで必要なものは、より早くする必要があります

ヘッダーは、その前に含まれている他のヘッダーに依存するべきではありません!ヘッダーが必要な場合は、ヘッダーのみが含まれます。ヘッダーガードは、複数の包含を防ぎます。

#ifndef FOO_HEADER_H
#define FOO_HEADER_H
...
#endif

[〜#〜]編集[〜#〜]

この回答を書いたので、コード内のincludeディレクティブの順序を変更しました。現在、私は常にヘッダーを標準化の昇順で配置しようとしているので、プロジェクトのヘッダーが最初に来て、次にサードパーティライブラリのヘッダー、次に標準のヘッダーが続きます。

たとえば、私のファイルの1つが、私が作成したライブラリ、Qt、Boost、および標準ライブラリを使用している場合、次のようにインクルードを注文します。

//foo.cpp
#include "foo.hpp"

#include <my_library.hpp>
// other headers related to my_library

#include <QtCore/qalgorithms.h>
// other Qt headers

#include <boost/format.hpp> // Boost is arguably more standard than Qt
// other boost headers

#include <algorithms>
// other standard algorithms

これを行う理由は、自分のヘッダーで欠落している依存関係を検出するためです。たとえば、my_library.hppstd::copyを使用しますが、<algorithm>は含まないとします。 <algorithm>foo.cppの後にそれを含めると、この欠落している依存関係は見過ごされます。それどころか、今提示した順序では、コンパイラーはstd::copyが宣言されていないと文句を言い、my_library.hppを修正できるようにします。

各「ライブラリ」グループでは、includeディレクティブをアルファベット順に並べて、見つけやすくするようにしています。

ちなみに、ヘッダーファイル間の依存関係を最大限に制限することもお勧めします。ファイルには、できるだけ少ないヘッダー、特にヘッダーファイルを含める必要があります。実際、含めるヘッダーが多いほど、何かが変更されたときに再コンパイルする必要のあるコードが多くなります。これらの依存関係を制限する良い方法は、前方宣言を使用することです。これは、ヘッダーファイルで十分であることがよくあります( 前方宣言はいつ使用できますか? を参照)。

6
Luc Touraille

Google C++スタイルガイド、インクルードの名前と順序

Dir2 /foo2.hの内容を実装またはテストすることを主な目的とするdir/foo.ccで、インクルードを次のように注文します。

  • dir2/foo2.h(推奨される場所-以下の詳細を参照)。
  • Cシステムファイル。
  • C++システムファイル。
  • 他のライブラリの.hファイル。
  • プロジェクトの.hファイル。
5
Igor Oks

以前はアルファベット順に並べていました(見つけやすい)

3
Gambrinus

「方法」は明らかではありませんが、「何」は明白です。あなたの目標は、ヘッダーファイルをインクルードする順序が決して重要ではないことを確認することです(そして私は「決して!」を意味しません)。

ヘッダーファイルの1つだけを含むcppファイル(ヘッダーファイルごとに1つ)をビルドするときに、ヘッダーファイルがコンパイルされるかどうかをテストすることをお勧めします。

2
Benoît

.cppファイルの場合、クラスのヘッダーまたは最初に実装するものをインクルードする必要があります。これにより、このヘッダーに一部のインクルードが欠落している場合に対応できます。その後、ほとんどのコーディングガイドラインには、最初にシステムヘッダーが含まれ、次にプロジェクトヘッダーが含まれる傾向があります。たとえば、 Google C++スタイルガイド です。

1
Anteru

これは依存関係であり、ヘッダーに何を入れるかに大きく依存します。実際には、これについて本当に悪名高く、インクルードを厳密に保つために最小限に抑えることができますが、最終的にはインクルージョンガードを使用したいというシナリオに遭遇します。

#ifndef MY_HEADER_H
#define MY_HEADER_H
//...
#endif

問題は最初はそれほど明白ではありませんが、ソフトウェアの複雑さが増すにつれて、依存関係も増します。あなたはうまくやることができ、それについて賢くすることができますが、より大きなC++プロジェクトは一般的にインクルードでいっぱいです。試すことはできますが、できることはそれだけです。ですから、勤勉になり、あなたのインクルードについて考えてください、はい!しかし、ある時点で確実に循環依存関係が発生するため、包含ガードが必要になります。

0
John Leidegren

ヘッダーに他のヘッダーが必要な場合は、そのヘッダーにそれらを含めるだけです。

ポインターまたは参照を渡し、可能な場合は前方宣言するようにコードを構造化してください。

実装では、それを定義するヘッダーを最初にリストする必要があります(Visual Studioでpchを使用している場合を除き、stdafxが最初に表示されます)。

私は通常、必要に応じてそれらをリストします。

0
graham.reeds