Definire la classe C ++ in uno o più file

3

Quando si crea una classe C ++, quale è la migliore pratica >

  • Inserisci l'intera definizione di classe e le funzioni membro in un file di intestazione
  • Inserisci la definizione della classe e le dichiarazioni di funzione nel file di intestazione e inserisci le definizioni di funzione in un file sorgente separato
  • Metti l'intera definizione di classe e decidi le funzioni membro in un file sorgente?

Mi rendo conto che puoi farlo in uno di questi tre modi, ma mi chiedo se c'è un modo preferito / più veloce. Qualsiasi informazione sarebbe ottima.

    
posta Mark Skelton 01.06.2016 - 21:00
fonte

3 risposte

8

Dipende, come al solito.

In genere, è consigliabile suddividere ciascuna classe in un file di intestazione ( .h o .hpp ) e di origine ( .cpp ), dove si inserisce tutto ciò che è possibile nel file di origine * , perché accelera notevolmente la costruzione del tuo programma. Questo è incredibilmente importante nello sviluppo del mondo reale perché i progetti di grandi dimensioni possono richiedere da 15 minuti a diverse ore per ricompilare e collegare completamente. Se cambi qualcosa in un file sorgente, il compilatore deve solo ricompilare quel file cpp in un file oggetto e collegare i programmi che includono questo file oggetto. Se modifichi qualcosa in un file di intestazione, il compilatore deve ricompilare tutti i file cpp che includono quell'intestazione e collegare tutti i programmi che includono uno di questi file oggetto.

Se la classe è leggera e molto improbabile da cambiare, di solito è meglio avere tutto in un file di intestazione. Un esempio potrebbe essere una classe che funge da ID strongmente tipizzato e ha solo un costruttore e un operatore di confronto. L'utilizzo di un solo file di intestazione semplifica la lettura del codice e in questo caso speciale non danneggia il tempo di compilazione poiché la classe non cambierà mai.

Se la classe è un modello, di solito non è possibile inserire nulla in un file cpp (a meno che non si utilizzi la specializzazione del modello), ma è spesso convenzione collocare le definizioni sotto la dichiarazione della classe nel file di intestazione, usando la inline keyword per consentire la compilazione.

* Puoi mettere ancora di più nel file sorgente se il tuo progetto soffre strongmente delle dipendenze dell'intestazione e del tempo di compilazione risultante: pImpl Idiom

    
risposta data 01.06.2016 - 21:12
fonte
2

Normalmente inserisci la definizione della classe e le dichiarazioni di funzione nel file di intestazione. E le definizioni delle funzioni in un file sorgente (* .cpp).

Il motivo per cui la definizione della classe e le dichiarazioni di funzione nel file di intestazione sono in modo che altre parti del software possano includere l'intestazione e utilizzare la classe e il suo metodo.
Il motivo per cui le definizioni del metodo in un file cpp-source era che i metodi dovrebbero essere definiti una sola volta. I compilatori moderni (ad esempio C ++ - 14 e successivi) possono far fronte allo stesso metodo definito più volte (dato che tutte le definizioni sono uguali, come nel caso dei file di intestazione inclusi). Tuttavia, la maggior parte dei programmatori C ++ si aspetta che le definizioni dei metodi siano nei file cpp e solo nei file di intestazione quando i metodi dovrebbero essere inline, quindi consiglierei di mettere i metodi nei file cpp.

    
risposta data 01.06.2016 - 21:14
fonte
1

Questo è probabilmente soggettivo, ma è una domanda interessante. Una classe in C ++ viene utilizzata per rappresentare diversi concetti distinti:

  1. Un'interfaccia
  2. Un oggetto
  3. Un tipo

Un'interfaccia coinvolgerà virtual void foo() = 0 e (si spera) nessuna implementazione. Un oggetto raggrupperà alcuni stati con alcuni metodi correlati, ad es. %codice%. Un tipo viene utilizzato per controllare il processo di compilazione, ma non ha uno scopo al di là di questo: potrebbe essere semplice come std::vector<int> o struct tag; .

Credo che se la classe e i metodi debbano essere suddivisi, dipende da quale delle categorie di cui sopra la stai usando. Un'interfaccia sposta tutto ciò che può nel file sorgente. È probabile che un oggetto sia una combinazione di piccoli metodi inline, scritti nell'intestazione e funzioni più grandi, forse con dipendenze, nella sorgente. Un tipo puro tende a essere coinvolto con i modelli e interamente nell'intestazione.

Tutto ciò detto, la maggior parte delle forme di "best practice" equivalgono a (compromessi tra) riducendo al minimo la duplicazione e minimizzando l'accoppiamento. Se applichiamo questi obiettivi alle classi, probabilmente vogliamo inserire qualsiasi metodo che estrae le dipendenze da altrove nel file di origine per ridurre al minimo l'accoppiamento e tutti gli altri nell'intestazione, quindi non è necessario digitare abbastanza. Scrivere una classe interamente in un file sorgente è grande fino a quando non è necessario condividerlo con altre unità di compilazione, ma fino ad allora, provaci.

Questo è complicato dai modelli. Se la classe in questione è basata su modelli, si è obbligati a scegliere tra la scrittura di gran parte di esso nell'intestazione o l'istanzializzazione esplicita per un set noto di tipi in un singolo file sorgente. Non posso difenderlo come best practice, ma tendo a scrivere classi di modelli interamente nei file di intestazione, calcolando il codice di tipo agnostico che esiste nelle funzioni libere.

    
risposta data 02.06.2016 - 00:41
fonte

Leggi altre domande sui tag