#.hまたは.c / .cppに含める?


118

CまたはC ++のいずれかでコーディングする場合、どこに#include

callback.h:

#ifndef _CALLBACK_H_
#define _CALLBACK_H_

#include <sndfile.h>
#include "main.h"

void on_button_apply_clicked(GtkButton* button, struct user_data_s* data);
void on_button_cancel_clicked(GtkButton* button, struct user_data_s* data);

#endif

callback.c:

#include <stdlib.h>
#include <math.h>

#include "config.h"

#include "callback.h"
#include "play.h"

void on_button_apply_clicked(GtkButton* button, struct user_data_s* data) {
  gint page;
  page = gtk_notebook_get_current_page(GTK_NOTEBOOK(data->notebook));

  ...

すべてのインクルードは.hまたは.c / .cppのいずれか、または両方に含める必要がありますか?


2
私はこの周りをオンにして聞いてみよう:何だったあなたの callback.hにsndfile.hとmain.hを置くことを決定するための基準は?
Owen S.

回答:


161

することができます限り入れ.cとでできるだけ.h。中に含まれる.c1つのファイルがコンパイルされますが、ために含まれている場合にのみ含まれている.h用途にそれをすることをすべてのファイルに含まれる必要があります。


6
真実ですが#ifndef _CALLBACK_H_、その上にあるは、コンパイラがそれを複数回処理するのを妨げていませんか?
hytromo 2014

11
@ user9379これにより、.cまたは.cppファイルごとに複数回含まれるのを防ぐことができます。ただし、通常、各.cファイルまたは.cppファイルは個別にビルドされます。つまり、コンパイルした.cファイルまたは.cppファイルごとに.hが再解析されます。
ブレンダンロング

2
.hインクルードのループが原因でエラーが発生しないようにするために、できるだけ少なくする主な理由は、いくつかあると思います。例:2つのクラスは、それらの実装では相互に必要ですが、宣言では必要ありません。両方のインクルードを.cppsに配置すると、エラーを回避できます。
コドスコープ2017年

1
@ Qu'est-cet'yontこれが、特定のことを.hファイルに入れられない理由です。この答えは、あなたがそれよりもさらに少ない数を置くべき理由についてです。
ブレンダンロング

@BrendanLongわかりました。ただし、コンテンツを1回だけ含めるように正しいマクロを内部に配置する場合、同じヘッダーを複数回含めることは重要ではありません。したがって、コードを修正することで、将来的にエラーが発生する可能性を減らすことは、さらに少なくすることだと思います。
コドスコープ2017年

55

別の.hファイルにヘッダーを含める必要があるのは、そのヘッダーの型定義にアクセスする必要がある場合のみです。例えば:

#ifndef MY_HEADER_H
#define MY_HEADER_H

#include <stdio.h>

void doStuffWith(FILE *f); // need the definition of FILE from stdio.h

#endif

上記の例のように、ヘッダーAがヘッダーBに依存している場合、ヘッダーAにはヘッダーBを直接含める必要があります。依存関係を満たすために.cファイルのインクルードを順序付けしないでください(つまり、ヘッダーAの前にヘッダーBを含めます)。それは、起こるのを待っている胸焼けの大昔の山です。私は真剣です。私はその映画に何度か出演したことがありますが、それは常に東京の炎の中で終わりました。

はい、これによりファイルが複数回インクルードされる可能性がありますが、複数の宣言/定義エラーから保護するために適切なインクルードガードが設定されている場合、数秒のビルド時間は心配する価値がありません。依存関係を手動で管理しようとすると、お尻の痛みです。

もちろん、あなたがいないファイルを含むべきではありません必要に。


10

できるだけ多くのインクルードをcppに入れ、hppのhppファイルで必要なものだけを入れます。hppファイルの相互参照が少なくなるため、これはコンパイルを高速化するのに役立つと思います。

インクルードの依存関係チェーンをさらに削減するために、hppファイルで前方宣言を使用することも検討してください。


1
ああ。前方宣言の事は面白いです。
ブレンダンロング

パラッパ、前方宣言は循環参照シナリオで非常に役立ちます。しかし、それらは他のシナリオでは良い方法でしょうか?(私はC ++で新しいので、正直に尋ねています)
Dzyann 2013年

5

私の場合、コードをコンパイルするために他の多くのヘッダーファイルを使用する#include <callback.h>必要はありません#include。ではcallback.h、あなた、それに対してコンパイルするために必要なすべてのものを含める必要があります。しかし、それ以上はありません。

ヘッダーファイル(などclass GtkButton;)で前方宣言を使用するだけで十分かどうかを検討し、ヘッダー内の#includeディレクティブの数を減らすことができます(さらに、コンパイル時間と複雑さも)。


同意しません。全世界をHファイルに含めると、依存関係チェーンが増加し、コンパイル時間が長くなります。
John Dibling

私の答えは、私が提案を含め、ヘッダファイルに全世界を含むことはお勧めしませんでしただけで十分なので、APIの利用者は、依存関係を探すのに時間を費やす必要はありません。
Johnsyweb
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.