Capire questo problema è fondamentalmente capire come funzionano le unità di compilazione C++. Le cose nei file di intestazione sono fondamentalmente incollate nel codice sorgente di un gruppo di unità di compilazione per le dichiarazioni #include
. Ogni unità di compilazione viene compilata in un file oggetto, i file oggetto vengono collegati e si verificano conflitti a causa del fatto che tali elementi vengono replicati dappertutto.
Le eccezioni sono cose che (storicamente, almeno) non entrano nel file oggetto perché il compilatore si occupa direttamente di esse (ad es. Funzioni inline) e cose che non possono essere compilate in una unità e collegate a un altro perché non sono completamente definiti (modelli). Le funzioni template spesso vengono istanziate in modo identico in più unità di compilazione e il linker ha speciali intelligenze per scartare i duplicati.
Ciò significa che la separazione dell'interfaccia e dell'implementazione nei file di intestazione e corpo non è molto pulita. Ada ha una separazione molto più pulita - ma un processo di compilazione più complesso per compensare IIRC. Java ha semplicemente rilasciato i file separati per l'interfaccia e l'implementazione.
I linker sono diventati molto più sofisticati nel corso degli anni e hanno assorbito parte del lavoro del compilatore, e molte di queste spiegazioni sono semplicemente sbagliate in questi giorni, eppure i modelli di base rimangono. Le funzioni template e le funzioni inline possono (e spesso devono) andare nell'intestazione, insieme a tutte le dichiarazioni condivise del codice don -t-direttamente-generate-oggetto-oggetto. Le definizioni di funzioni normali non dovrebbero essere in un file di intestazione.
Come per i modelli, non è strettamente vero che è necessario inserire le definizioni di funzione (membro) nel file di intestazione. È possibile inserire le definizioni in un file sorgente e utilizzare l'istanziazione esplicita del modello per rendere disponibili particolari specializzazioni ... –
@STingRaySC Sì, ho avuto alcuni ricordi vaghi dai modelli C++ che è possibile, anche se non l'ho mai fatto da solo. Tuttavia, ho cercato di dare una regola generale che è buona per i principianti e quasi sempre applicabile. Entrare nei casi speciali è per gli esperti (di cui non sono uno :-) –
E non devi fornire implementazioni di modelli nel file di intestazione se il tuo compilatore supporta l'esportazione – smerlin