#include в .h или .c/.cpp?

При кодировании в 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 или в обоих, как я сделал здесь?

Ответ 1

Поместите как можно больше в .c и как можно меньше в .h. Вложения .c включаются только тогда, когда этот один файл скомпилирован, но включенные для .h должны быть включены каждым файлом, который его использует.

Ответ 2

Единственный раз, когда вы должны включить заголовок в другой файл .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 напрямую. Do NOT попытайтесь заказать ваши включенные в .c файл для удовлетворения зависимостей (то есть, включая заголовок B перед заголовком A); это большая старина изжоги, ожидающая своего служения. Я серьезно. Я был в этом фильме несколько раз, и он всегда заканчивался Токио в огне.

Да, это может привести к тому, что файлы будут включены несколько раз, но если у них есть надлежащие включенные охранники, настроенные для защиты от нескольких ошибок объявления/определения, то несколько лишних секунд времени сборки не стоит беспокоиться. Попытка управлять зависимостями вручную - это боль в заднице.

Конечно, вы не должны включать файлы, в которых вам не нужно.

Ответ 3

Поместите как можно больше в ваш cpp и только те, которые необходимы файлу hpp в hpp. Я считаю, что это поможет ускорить компиляцию, так как hpp файлы будут перекрестно привязаны меньше.

Также рассмотрите возможность использования форвардных объявлений в вашем файле hpp, чтобы еще больше уменьшить цепочку зависимостей include.

Ответ 4

Если я #include <callback.h>, я не хочу иметь #include множество других файлов заголовков, чтобы получить код для компиляции. В callback.h вы должны включить все, что необходимо для компиляции. Но ничего больше.

Подумайте, достаточно ли использования форвардных объявлений в вашем файле заголовка (например, class GtkButton;), что позволит вам уменьшить количество директив #include в заголовке (и, в свою очередь, мое время и сложность компиляции).