2010-06-08 15 views
71

Durante la codifica in C o C++, dove dovrei avere lo #include?#include in .h o .c/.cpp?

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)); 

    ... 

caso tutti comprende essere sia nel .h o .c/cpp, o entrambi, come ho fatto io qui?

+2

Permettetemi di capovolgerlo e chiedere: quali erano i vostri criteri per decidere di inserire sndfile.h e main.h in callback.h? –

risposta

98

Inserire il più possibile nello .c e il meno possibile nello .h. Gli include nello .c sono inclusi solo quando viene compilato quel file, ma gli include per lo .h devono essere inclusi da ogni file che lo utilizza.

+4

Vero, ma non il '#ifndef _CALLBACK_H_', in cima ad esso, impedisce al compilatore di elaborarlo più di una volta? – hakermania

+8

@ user9379 Ciò impedirà che venga incluso più di una volta per file .c o .cpp. Ogni file .c o .cpp viene generalmente creato singolarmente, il che significa che un file .h verrà nuovamente analizzato per ogni file .c o .cpp che viene compilato. –

+0

Penso che il motivo principale per mettere il meno possibile in '.h' è di evitare in alcuni casi un errore a causa di un ciclo di inclusione.Esempio: due classi hanno bisogno l'una dell'altra per le loro implementazioni, ma non per le loro dichiarazioni. Mettere entrambi include in '. Cpp's eviterà un errore. – Codoscope

5

Se I #include <callback.h>, non voglio avere #include molti altri file di intestazione per ottenere il mio codice da compilare. In callback.h dovresti includere tutto ciò che è necessario per compilare. Ma niente di più.

Considerare se utilizzare le dichiarazioni di inoltro nel file di intestazione (ad esempio class GtkButton;) sarà sufficiente, consentendo di ridurre il numero di direttive #include nell'intestazione (e, a sua volta, il tempo e la complessità della compilazione).

+0

Non sono d'accordo. Includere il mondo intero nei file H aumenta la catena di dipendenze e quindi i tempi di compilazione. –

+0

La mia risposta non ha raccomandato di includere tutto il mondo nel file di intestazione, ho suggerito di includere * solo * abbastanza in modo che l'utente dell'API non debba dedicare tempo alla ricerca delle dipendenze. – Johnsyweb

8

Metti il ​​maggior numero di include nel tuo cpp possibile e solo quelli che sono necessari nel file hpp nell'hpp. Credo che ciò contribuirà ad accelerare la compilazione, poiché i file hpp avranno meno riferimenti incrociati.

Considerare inoltre l'utilizzo di forward declarations nel file hpp per ridurre ulteriormente la catena di dipendenze di inclusione.

+0

Oo. La cosa delle dichiarazioni avanzate è interessante. –

+0

Parappa, le dichiarazioni anticipate sono molto utili negli scenari di riferimento circolare. Ma sarebbero una buona pratica in altri scenari? (Io nuovo in C++, quindi sto chiedendo onestamente) – Dzyann

28

L'unica volta che è necessario includere un'intestazione all'interno di un altro file .h è se è necessario accedere a una definizione di tipo in tale intestazione; ad esempio:

#ifndef MY_HEADER_H 
#define MY_HEADER_H 

#include <stdio.h> 

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

#endif 

Se intestazione A dipende intestazione B, come nell'esempio precedente, allora A deve includere intestazione intestazione B direttamente. Do NON prova ad ordinare il tuo include nel file .c per soddisfare le dipendenze (cioè, includendo l'intestazione B prima dell'intestazione A); questo è un grosso mucchio di bruciore di stomaco che aspetta di accadere. Voglio dire che. Sono stato in quel film diverse volte, e si è sempre concluso con Tokyo in fiamme.

Sì, questo può causare l'inclusione di file più volte, ma se dispongono di protezioni di inclusione appropriate impostate per proteggere da più errori di dichiarazione/definizione, non vale la pena preoccuparsi di alcuni secondi extra di tempo di costruzione. Cercare di gestire le dipendenze manualmente è un rompicapo.

Ovviamente, non dovresti includere file in cui non è necessario a.