どのような順序でファイルを指定する必要がありますか。つまり、あるヘッダーを別のヘッダーの前に含める理由は何ですか。
たとえば、システムファイル、STL、およびBoostはローカルインクルードファイルの前または後にありますか?
どのような順序でファイルを指定する必要がありますか。つまり、あるヘッダーを別のヘッダーの前に含める理由は何ですか。
たとえば、システムファイル、STL、およびBoostはローカルインクルードファイルの前または後にありますか?
回答:
コンパイルされる限り、推奨される順序はないと思います!厄介なのは、一部のヘッダーで最初に他のヘッダーを含める必要がある場合です...これは、インクルードの順序ではなく、ヘッダー自体の問題です。
私の個人的な好みは、各サブセクションをアルファベット順にローカルからグローバルに移動することです。
1.の私の理論的根拠は、各ヘッダー(cppがある)が#include
前提条件なしで終了できることを証明する必要があるということです(末端技術:ヘッダーは「自己完結型」)。そして、残りはそこから論理的に流れるようです。
心に留めておくべき重要なことは、ヘッダーが最初に含まれている他のヘッダーに依存するべきではないということです。これを保証する1つの方法は、他のヘッダーの前にヘッダーを含めることです。
「Thinking in C ++」では、Lakosの「Large Scale C ++ Software Design」を参照して、これについて特に言及しています。
外部から提供された宣言や定義なしで、コンポーネントの.hファイル自体が確実に解析されるようにすることで、潜在的な使用エラーを回避できます... .cファイルの最初の行に.hファイルを含めることで、重要な部分がないコンポーネントの物理インターフェイスに固有の情報の一部が.hファイルにありません(または、ある場合は、.cファイルをコンパイルしようとするとすぐにわかります)。
つまり、次の順序で含めます。
この順序に含まれることに問題があるヘッダーがある場合は、それらを修正するか(使用している場合)、使用しないでください。きれいなヘッダーを書かないボイコットライブラリ。
GoogleのC ++スタイルガイドはほぼ逆のことを主張しており、まったく正当化されていません。私は個人的にラコスのアプローチを好む傾向があります。
私は、大多数の問題を回避する2つの単純なルールに従います。
私は以下のガイドラインにも従います:
言い換えると:
#include <stdio.h>
#include <string.h>
#include "btree.h"
#include "collect_hash.h"
#include "collect_arraylist.h"
#include "globals.h"
ガイドラインですが、それは主観的なことです。一方、私は厳格に施行し、不快なサードパーティの開発者が私のビジョンにサブスクライブしない場合は、インクルードガードとグループ化されたインクルードを使用して「ラッパー」ヘッダーファイルを提供するところまで行っています:-)
自分のレンガを壁に追加します。
だから私は通常このように行きます:
// myproject/src/example.cpp
#include "myproject/example.h"
#include <algorithm>
#include <set>
#include <vector>
#include <3rdparty/foo.h>
#include <3rdparty/bar.h>
#include "myproject/another.h"
#include "myproject/specific/bla.h"
#include "detail/impl.h"
次のグループから空白行で区切られた各グループ:
また、システムヘッダーとは別に、各ファイルは名前空間の名前が付いたフォルダーにあります。これは、この方法で追跡しやすいためです。
#define
他のコードをめちゃくちゃにすることについて悪いこと)と暗黙の依存関係を防ぐことの両方によって。たとえば、コードベースのヘッダーファイルがfoo.h
実際に依存し<map>
ているが、.cc
ファイルで使用されているすべての場所で、<map>
既にインクルードされている場合、おそらく気付かないでしょう。foo.h
最初に含めずに誰かが含めようとするまで<map>
。そして、彼らはイライラするでしょう。
.h
少なくとも1つの問題があるためです.cpp
(実際、私の個人コードでは、ユニットテストに関連付けられたものが最初に含まれ、ソースコードはそれを正当なグループに含めます)。影響を受けないことに関して、いずれかのヘッダーに含まれている<map>
場合、その後に含まれるすべてのヘッダーが影響を受けるため、私にとっては負けた戦いのようです。
Header corresponding to this cpp file first (sanity check)
です。#include "myproject/example.h"
すべてのインクルードの最後に移動した場合、特に何かありますか?
私はお勧め:
そしてもちろん、可能な場合、各セクション内のアルファベット順。
#include
ヘッダーファイルで不要なを回避するために、常に前方宣言を使用してください。
これは正気の世界のどこでも推奨される方法ではないと確信していますが、同じシステム内で字句的にソートされたファイル名の長さでシステムインクルードを並べるのが好きです。そのようです:
#include <set>
#include <vector>
#include <algorithm>
#include <functional>
include-order依存関係の恥を避けるために、他の人々の前に独自のヘッダーを含めることは良い考えだと思います。
windows.h
。
最初に、.cpp ...に対応するヘッダーを含めます。つまり、他のものsource1.cpp
を含めるsource1.h
前に含める必要があります。私が考えることができる唯一の例外は、プリコンパイル済みヘッダーでMSVCを使用する場合stdafx.h
です。その場合、何よりも先に含める必要があります。
理由:source1.h
他のファイルの前にbefore を含めることで、依存関係なしにスタンドアロンで動作できるようになります。source1.h
後日、依存関係が発生した場合、コンパイラは、必要な転送宣言をに追加するよう直ちに警告しますsource1.h
。これにより、依存関係者がヘッダーを任意の順序で含めることができます。
例:
source1.h
class Class1 {
Class2 c2; // a dependency which has not been forward declared
};
source1.cpp
#include "source1.h" // now compiler will alert you saying that Class2 is undefined
// so you can forward declare Class2 within source1.h
...
MSVCユーザー:プリコンパイル済みヘッダーの使用を強くお勧めします。したがって、#include
標準ヘッダー(および変更されない他のヘッダー)のすべてのディレクティブをに移動しstdafx.h
ます。
これは、C / C ++の世界では難しい問題であり、標準を超える要素がたくさんあります。
ヘッダーファイルの順序は、squelartが言ったように、コンパイルされる限り、深刻な問題ではないと思います。
私の考えは次のとおりです。これらのすべてのヘッダーに記号の競合がない場合、どの順序でも問題ありません。ヘッダーの依存関係の問題は、欠陥のある.hに#include行を追加することで後で修正できます。
実際の面倒は、一部のヘッダーが(#if条件をチェックすることによって)その上にあるヘッダーに従ってアクションを変更するときに発生します。
たとえば、VS2005のstddef.hには、次のものが含まれます。
#ifdef _WIN64
#define offsetof(s,m) (size_t)( (ptrdiff_t)&(((s *)0)->m) )
#else
#define offsetof(s,m) (size_t)&(((s *)0)->m)
#endif
ここで問題:カスタムヘッダー( "custom.h")がありoffsetof
、システムヘッダーで提供されていない古いコンパイラーを含め、多くのコンパイラーで使用する必要がある場合は、ヘッダーに書き込む必要があります。
#ifndef offsetof
#define offsetof(s,m) (size_t)&(((s *)0)->m)
#endif
そして、必ずすべてのシステムヘッダーの#include "custom.h"
後にユーザーに伝えるようにしてください。そうしないと、offsetof
stddef.h の行がマクロ再定義エラーをアサートします。
今後は、このようなケースに遭遇しないようお祈り申し上げます。