2009-05-17 23 views
44

Perché ho creato i file .cpp e li ho trasferiti in file .h, l'unica differenza che posso trovare è che non puoi # include i file .cpp. C'è qualche differenza che mi manca?Qual è la differenza tra un file .cpp e un file .h?

+7

in realtà, è possibile includere file .cpp. Puoi includere tutto ciò che vuoi. –

+0

Per comprendere le risposte delle persone di seguito, potrebbe essere necessario fare un'altra domanda: ad esempio "Qual è la differenza tra una 'dichiarazione' e una 'definizione' in C++?" – ChrisW

+1

Conosco la differenza tra una dichiarazione e una definizione. –

risposta

42

Il sistema di compilazione C++ (compilatore) non conosce differenze, quindi è una delle convenzioni.

La convenzione è che i file .h sono dichiarazioni ei file cpp sono definizioni.

Ecco perché i file .h sono #inclusi - includiamo le dichiarazioni.

+0

Il sistema di compilazione C++ si differenzia: prova a eseguire g ++ su un file .h e un file .cpp e vedi cosa succede, ad esempio. –

+0

So che i file .cpp sono usati (il più delle volte) per definire funzioni/classi/etc che sono stati dichiarati in file .h, ma è possibile definire anche variabili in file .h. –

+5

@Neil Butterworth: Sì, il compilatore G ++ comprende la convenzione, ma è possibile farlo compilare forzando la lingua. –

0

Per convenzione, i file .h sono inclusi da altri file e mai compilati direttamente da soli. I file .cpp sono - di nuovo, per convenzione - le radici del processo di compilazione; essi includono file .h direttamente o indirettamente, ma generalmente non file .cpp.

17

Il file .cpp è l'unità di compilazione: è il vero file di codice sorgente che verrà compilato (in C++).

I file .h (header) sono file che saranno virtualmente copiati/incollati nei file .cpp in cui appare l'istruzione #include precompilatore. Una volta inserito il codice delle intestazioni nel codice .cpp, può iniziare la compilazione di .cpp.

+0

Perché dici il file .cpp e non un file .cpp? –

+9

@ Keand64: Poiché il compilatore esamina solo * un * file .cpp alla volta durante la compilazione delle cose. Legge un file .cpp, legge tutti i file .inclusi .h, compila il tutto, scrive un file .o (o .obj) e quindi passa al successivo file .cpp. –

6

.h file o file di intestazione, vengono utilizzati per elencare le variabili di istanza pubblicamente disponibili ei metodi nella dichiarazione di classe. I file .cpp, o file di implementazione, vengono utilizzati per implementare effettivamente tali metodi e utilizzare tali variabili di istanza.

Il motivo per cui sono separati è perché i file .h non sono compilati in codice binario mentre i file .cpp lo sono. Prendi una biblioteca, per esempio. Dì che sei l'autore e non vuoi che sia open source. Quindi distribuisci la libreria binaria compilata e i file di intestazione ai tuoi clienti. Ciò consente loro di vedere facilmente tutte le informazioni sulle classi della tua biblioteca che possono utilizzare senza essere in grado di vedere come hai implementato questi metodi. Sono più per le persone che usano il tuo codice piuttosto che per il compilatore. Come detto prima: è la convenzione.

1

Altri hanno già offerto buone spiegazioni, ma ho pensato di chiarire le differenze tra le varie estensioni:

 
    Source Files for C: .c 
    Header Files for C: .h 

    Source Files for C++: .cpp 
    Header Files for C++: .hpp 

Naturalmente, come è già stato sottolineato, queste sono solo convenzioni. Il compilatore in realtà non gli presta alcuna attenzione - è puramente a beneficio del programmatore.

+3

La maggior parte delle persone usa effettivamente .h anche per C++. – Zifre

+0

@Zifre: Sì, quindi dico che sono * le convenzioni di denominazione * raccomandate *, anche se molte potrebbero non seguirle. – Noldorin

1

Una buona regola empirica è "i file .h dovrebbero avere dichiarazioni [potenzialmente] utilizzate da più file sorgente, ma nessun codice viene eseguito".

5

Un colpo di testa (.h, .hpp, ...) File contiene

  • definizioni di classe (class X { ... };)
  • definizioni di funzioni in linea (inline int get_cpus() { ... })
  • dichiarazioni di funzione (void help();)
  • dichiarazioni di oggetti (extern int debug_enabled;)

Un file sorgente (.c , .cpp, .cxx) contiene

  • definizioni di funzione (void help() { ... } o void X::f() { ... })
  • definizioni di oggetto (int debug_enabled = 1;)

Tuttavia, la convenzione che le intestazioni sono nominati con un .h file suffisso di origine e sono contrassegnati dal suffisso .cpp non è davvero richiesto. Si può sempre dire a un buon compilatore come trattare alcuni file, indipendentemente dal suffisso nome file (-x <file-type> per gcc. Come -x c++).

I file di origine conterranno definizioni che devono essere presenti solo una volta nell'intero programma. Quindi se includi un file sorgente da qualche parte e poi colleghi il risultato della compilazione di quel file e poi quello del file sorgente stesso, allora otterrai degli errori linker, perché hai quelle definizioni che ora appaiono due volte: una volta nel incluso il file sorgente e quindi nel file che lo includeva. Ecco perché hai avuto problemi con l'inclusione del file .cpp.

12

Conosco la differenza tra una dichiarazione e una definizione.

considerando quanto segue:

  • Un file CPP include le definizioni da qualsiasi colpo di testa che comprende (perché il file CPP e l'intestazione insieme diventano una sola 'unità di traduzione')
  • Un file di intestazione potrebbe essere incluso da più di un file di CPP
  • Il linker in genere non piace nulla definita in più di un file CPP

Il pertanto qualsiasi definizione in un file di intestazione dovrebbe essere in linea o statica. I file di intestazione contengono anche dichiarazioni utilizzate da più di un file CPP.

Le definizioni che non sono né statiche né inline vengono inserite nei file CPP. Inoltre, tutte le dichiarazioni che sono necessarie solo all'interno di un file CPP vengono spesso inserite all'interno del file CPP stesso, invece di qualsiasi file di intestazione (condivisibile).

Problemi correlati