Inoltra dichiarazione vs include

12

Reduce the number of #include files in header files. It will reduce build times. Instead, put include files in source code files and use forward declarations in header files.

Ho letto questo qui. link .

Quindi dice che se una classe (classe A) nel file di intestazione non ha bisogno di usare la definizione effettiva di qualche classe (classe B). A quel punto possiamo usare la dichiarazione di inoltro invece di includere il particolare file di intestazione (di classe B).

Domanda: Se la classe (classe A) nell'intestazione se non usa la definizione effettiva di una particolare classe (classe B), Allora come la dichiarazione in avanti aiuta a ridurre il tempo di compilazione?

    
posta Nayana Adassuriya 23.04.2013 - 09:41
fonte

4 risposte

10

Il compilatore non si cura se la classe A usa la classe B. Sa solo che quando la classe A è compilata e non ha una dichiarazione precedente di classe B (forward forward o altro), va in panico e la contrassegna come un errore.

Ciò che è importante qui è che il compilatore sa che non hai provato a compilare un programma dopo che il tuo gatto ha camminato sulla tua tastiera e ha creato alcune lettere casuali che potrebbero essere o non essere interpretate come una classe.

Quando vede una inclusione, per poter usare qualsiasi informazione contenuta all'interno, deve aprire il file e analizzarlo (indipendentemente dal fatto che debba effettivamente farlo). Se quel file include anche altri file, anche questi devono essere aperti e analizzati, ecc. Se questo può essere evitato, è generalmente una buona idea usare invece una dichiarazione diretta.

Modifica : L'eccezione a questa regola è rappresentata dalle intestazioni precompilate. In questo caso, tutte le intestazioni vengono compilate e salvate per le compilazioni future. Se le intestazioni non cambiano, il compilatore può utilizzare in modo intelligente le intestazioni precompilate delle precedenti compilazioni e quindi ridurre i tempi di compilazione, ma funziona solo se non è necessario modificare le intestazioni.

    
risposta data 23.04.2013 - 09:51
fonte
2

perché quindi A.hpp non ha bisogno di includere #include B.hpp

quindi A.hpp diventa

class B;//or however forward decl works for classes

class A
{
    B* bInstance_;
//...
}

quindi, quando è incluso A.hpp, B.hpp non è incluso implicitamente e tutti i file che dipendono solo da A.hpp non devono essere ricompilati ogni volta che b.hpp cambia

    
risposta data 23.04.2013 - 09:49
fonte
2

Ricorda che il preprocessore C / C ++ è un processo di elaborazione separato, puramente testuale. La direttiva #include estrae il contenuto dell'intestazione inclusa e il compilatore deve analizzarlo. Inoltre, la compilazione di ogni .cpp è completamente separata, quindi il fatto che il compilatore abbia appena analizzato B.h durante la compilazione di B.cpp non lo aiuta di meno quando ne ha bisogno di nuovo durante la compilazione di A.cpp . E ancora quando si compila C.cpp . E D.cpp . E così via. E ciascuno di questi file deve essere ricompilato se qualsiasi file incluso in esso è stato modificato.

Quindi, la classe A utilizza la classe B e le classi C e D utilizzano la classe A , ma non è necessario modificare B . Se la classe A può essere dichiarata con la dichiarazione forward di B , allora B.h viene compilato due volte: quando si compila B.cpp e A.cpp (perché B è ancora necessario nei metodi di A ).

Ma quando A.h include B.h , è compilato quattro volte - quando compila B.cpp , A.cpp , C.cpp e D.cpp come le due successive ora includono indirettamente B.h .

Anche quando l'intestazione è inclusa più di una volta, il preprocessore deve ancora leggerlo ogni tempo. Salterà l'elaborazione del contenuto a causa della protezione #ifdef s, ma continua a leggerlo e deve cercare la fine della guardia, il che significa che deve analizzare tutte le direttive del preprocessore all'interno.

(Come accennato nell'altra risposta, le intestazioni precompilate tentano di aggirare questo problema, ma sono le proprie lattine di worm, in pratica si possono usare ragionevolmente per le intestazioni di sistema e solo se non ne si usano troppe, ma non per le intestazioni nel tuo progetto)

    
risposta data 23.04.2013 - 13:11
fonte
1

Una dichiarazione anticipata è molto più veloce da analizzare di un intero file di intestazione che potrebbe includere anche più file di intestazione.

Inoltre, se si modifica qualcosa nel file di intestazione per la classe B, tutto ciò che include quell'intestazione dovrà essere ricompilato. Con una dichiarazione anticipata, questo può essere solo il file sorgente in cui risiede l'implementazione di A. Ma se l'intestazione di A includesse effettivamente l'intestazione di B, anche tutto compreso a.hpp verrà ricompilato, anche se non usa nulla di B.

    
risposta data 23.04.2013 - 09:48
fonte

Leggi altre domande sui tag