2011-09-28 18 views
6

Stavo leggendo un vecchio libro di strutture dati e diceva che durante la programmazione delle classi di template dovresti includere il .cpp alla fine del file .h.Incluso .cpp alla fine del file di intestazione del modello

Per quanto ne so, è necessario eseguire implementazioni a funzioni complete nel file .h per qualsiasi funzione membro della classe template, a causa del modo in cui il compilatore di template funziona.

Le uniche funzioni che ho appreso potrebbero essere inserite in un file di implementazione per una classe modello erano le funzioni di specializzazione modello, ad esempio template<> Class<Type>::function_name().

Perché questo libro dovrebbe suggerire di includere il .cpp alla fine del .h? questo è solo un modo per separare le implementazioni in file diversi e farli compilare con l'intestazione? e se sì, dove metteresti delle vere specializzazioni? Suppongo che non potrebbero entrare nel file .cpp incluso nell'intestazione.

risposta

9

Molto probabilmente l'autore preferisce avere dichiarazione e definizione in file diversi, posso immaginarlo perché rende più facile saltare tra dichiarazioni e definizioni.

Ma l'estensione di file "cpp" è un po 'confusa. Di solito questi file sono chiamati "ipp" per "Inline C++".

+2

Non ho mai visto in vita mia questi file denominati 'ipp' –

+0

@JohnDibling: è tutto boost. Le domande a riguardo sono state persino sollevate qui su SO prima. –

+0

vedere http://stackoverflow.com/questions/543507/in-the-c-boost-libraries-why-is-there-a-ipp-extension-on-some-header-files –

3

Questo è probabilmente vecchio linguaggio, e penso che la tua analisi della separazione di implementazione e dichiarazione sia corretta. All'epoca in cui questo particolare libro era stato scritto, l'autore probabilmente pensava a un file cpp come al file in cui risiedevano le definizioni, e ai file h come ai file in cui risiedevano le dichiarazioni. Mettere le specializzazioni esplicite reali nel file precedente sarebbe, naturalmente, letale (o almeno inutile) al linker a causa di definizioni ripetute. Al giorno d'oggi, eviterei di nominare il file delle definizioni .cpp.

0

Per quanto ne so quello che dovete fare implementazioni di funzionalità complete nel file h per le funzioni di membro di classe template - è dovuto al modo in cui il modello opere compilatore.

Il libro presuppone che si disponga delle implementazioni di tutte le funzioni nel file .cpp.

Se le specializzazioni complete sono nel file cpp, non dovrebbero essere incluse nel file di intestazione. Molto probabilmente non verrà compilato se lo hai fatto. Poiché il compilatore vedrà più definizioni della stessa funzione del file di intestazione, generalmente saranno incluse in più file sorgente.

0

Se si desidera utilizzare un modello, l'intera definizione del modello deve essere visibile nella TU che crea un'istanza del modello. Quindi potresti semplicemente inserire definizioni complete nel file di intestazione.

È solo se si desidera mantenere la definizione della classe e gli organi delle funzioni della classe separati, quindi si potrebbe essere tentati di inserire tali definizioni di funzioni in un file separato. Tuttavia, la regola sopra rimane valida, quindi dovrai includere il file separato insieme all'intestazione in modo che chiunque possa utilizzare il modello.

È una questione di gusti. Se i corpi delle funzioni dei membri sono brevi, potresti anche definirli in linea. Inoltre, tieni presente che le funzioni definite all'interno della definizione di classe sono dichiarate implicitamente inline, mentre dovresti specificarlo esplicitamente se scrivi i corpi separatamente.

Un modello parzialmente specializzato è ancora un modello, quindi si applicano le stesse regole.

Un modello di classe completo specializzata è solo una classe ordinaria, in modo da trattare in quanto tale:

// FooInt.hpp 
template <typename> class Foo; 
template <> class Foo<int> 
{ 
    // your class here 
}; 

Una cosa si può avere avuto in mente è "modello di istanziazione esplicita", alla template class Foo<int>;. Questo è qualcos'altro; lascia un commento se sei interessato a utilizzarlo.

1

In primo luogo, non c'è nessuna regola che bisogna avere le implementazioni delle modelli nel file .h (o .hpp, o .hh); infatti, per qualsiasi cosa ma i modelli più semplici, consiglierei di non farlo. Devi includere l'implementazione, indipendentemente dal file. Quello che l'autore di probabilmente aveva in mente era di mettere l'implementazione in un file .cpp e includerlo. Suggerirei comunque di trovare un nome diverso, , dal momento che la maggior parte delle persone (e alcuni IDE) supporterà che sia necessario compilare tutti i file .cpp in .cpp. Una convenzione comune in cui .cc e .hh è le estensioni usuali per sorgenti e intestazioni è .tcc per le implementazioni del modello ; in un mondo Windows (dove lo .cpp è quasi universale), , consiglierei qualcosa come .tpp.

Si noti che le prime implementazioni dei modelli richiedevano l'implementazione in un .cpp. Queste implementazioni non hanno richiesto che fosse incluso (o permesso); il compilatore cercato il .cpp (o .cc) corrispondente al file .hpp (o .hh), in cui definizione della classe modello o dichiarazione di funzione è apparso, e generato un file sorgente manichino che comprendeva (e qualsiasi altra cosa che era necessario).

Problemi correlati