2011-02-07 14 views
7

Sono nuovo di C/C++, Sono confuso su chi segue:C++ Includi intestazione problema

  1. se devo mettere dichiarazioni di classe nel proprio file di intestazione, e l'attuazione effettiva in un altro file?
  2. Se devo mettere le intestazioni come <iostream> nel file example.h o in file di example.cpp?
  3. Se tutte le classi hanno bisogno di usare <iostream>, e includono file di intestazione di una classe in colpo di testa di un'altra classe, significa ho incluso <iostream> due volte?
  4. Se uso un sacco di classi STL, che cosa è una buona pratica da usare std::?
+1

# 4 è distinto abbastanza per meritare la sua stessa domanda – Cameron

+0

Queste sono domande decenti, ma combinarle tutte in una è "eccessivamente ampia". –

risposta

8

1.Whether dovrei mettere dichiarazioni di classe nel proprio file di intestazione, e l'attuazione effettiva in un altro file ?

È possibile scrivere la definizione di una classe e la definizione dei membri della classe separatamente nello stesso file di intestazione se si manipolano i modelli. Inoltre, se vuoi far funzionare i membri in linea, puoi definirli all'interno della definizione stessa della classe. In ogni altro caso, è meglio separare la definizione della classe (file .hpp) e la definizione dei membri della classe (.cpp).

2.Whether dovrei inserire intestazioni come nel file example.h o nel file example.cpp ?

Dipende se occorrono tali intestazioni nel file example.h o solo nel proprio file .cpp.

3. Se tutte le classi hanno bisogno di usare, e mi sono file di intestazione di una classe in colpo di testa di un'altra classe, vuol dire che incluso due volte?

Succede se non avvolgere le definizioni di classe per le seguenti macro:

#ifndef FOO_HPP 
#define FOO_HPP 
class { 
... 
}; 
#endif 

5.If ​​io uso molto classi STL, che cosa è una buona pratica da usare std: :?

Penso che sia meglio ogni volta che è possibile utilizzare std:: ogni volta anziché using namespace std. In questo modo utilizzerai solo gli spazi dei nomi di cui hai bisogno e il tuo codice sarà più leggibile perché eviterete i conflitti nello spazio dei nomi (immaginate due metodi che hanno lo stesso nome e appartengono a due diversi spazi dei nomi).

Ma la cosa più importante è comunque la domanda numero 4?

+1

Rimuovere i caratteri di sottolineatura doppio prima di "FOO_HPP" e lo inviterò.;) – Maxpm

+1

@Maxpm: Fatto :) –

1

In genere, si mettono le dichiarazioni di classe (incluse le dichiarazioni dei membri) nei file di intestazione e le definizioni delle funzioni membro (metodi) nei file di origine. Le intestazioni di solito hanno nomi come *.h o *.hpp. Per quanto riguarda il punto 3, dovresti inserire protezioni incluse nelle intestazioni in modo che possano essere incluse in sicurezza più volte nello stesso file sorgente; quindi puoi includerli ovunque ne hai bisogno. Non capisco il punto 5: stai chiedendo quando utilizzare la qualifica dello spazio dei nomi std::?

1

Per il problema "incluso due volte", ecco un modello comune per i file di intestazione:

// _BLAHCLASS_H_ should be different for each header, otherwise things will Go Bad. 
#ifndef _BLAHCLASS_H_ 
#define _BLAHCLASS_H_ 

... rest of header ... 

#endif 
+4

I nomi che iniziano con due caratteri di sottolineatura sono riservati all'implementazione del compilatore; dovresti usare un modello diverso per le tue guardie incluse (ad esempio 'BLAHCLASS_H_INCLUDED'). –

+1

Concordato al punto generale, ma qual è l'accordo con le persone che usano i caratteri di sottolineatura doppia (lo vedo ovunque). Questi nomi non sono riservati alle implementazioni? (Anche loro sembrano brutti) –

+0

oggi ho imparato qualcosa sui doppi underscore. – geofftnz

2
  1. In generale, sì. Aiuta con l'organizzazione. Tuttavia, su piccoli progetti potrebbe non essere un grosso problema.

  2. Sto avendo difficoltà a capire la domanda qui. Se stai chiedendo dove mettere la direttiva #include, il file di implementazione dovrebbe includere il file di intestazione.

  3. Sì, ma l'uso di include guards impedisce più inclusioni.

1
  1. Finché non sono modelli, in genere si. I modelli (nel bene o nel male) devono essere inseriti nelle intestazioni.
  2. Preferisco rendere ognuna delle mie intestazioni "standalone", quindi se qualsiasi altra intestazione è necessaria per il suo funzionamento, include quell'intestazione stessa (ad esempio, se ho una classe che utilizza std::string, l'intestazione per quella classe sarà
  3. No. Con alcune eccezioni speciali, le intestazioni standard devono essere scritte in modo da poterle includere più volte senza che cambi nulla (l'eccezione principale è /cassert, che può avere senso includere più di una volta)
  4. Non sono sicuro di quello che stai chiedendo.Se stai chiedendo di usare una direttiva come using namespace std;, allora è generalmente (anche se certamente non universalmente) detestavano. Una dichiarazione usando come using std::vector; è generalmente considerata meno problematica.
+0

Ci sono modi per separare un'implementazione di un modello dalla sua dichiarazione, ma probabilmente è oltre lo scopo di questa domanda. – Maxpm

2
  1. Normalmente si dovrebbe, ma per progetti relativamente piccoli è possibile evitare di avere un file di implementazione il più possibile;
  2. Se l'intestazione utilizza solo tipi incompleti dal <iostream>, è possibile evitare di includerlo, ma è necessario forward declarations per questi tipi (vedere When to use forward declaration?). Tuttavia, per semplicità, se il tipo usa template, normalmente includo la rispettiva intestazione;
  3. No. Il include guards garantisce che un'intestazione sia inclusa solo una volta nello stesso translation unit;
  4. Una buona pratica comune è quella di non inserire using namespace std in un file di intestazione. Sii consapevole anche dei conflitti nello spazio dei nomi;
Problemi correlati