Dovrei includere ogni intestazione?

Devo includere ogni intestazione anche se è stata inclusa in precedenza? O forse dovrei evitarlo quando posso? Per esempio. Se uso std::string e std::vector in qualche file. Se incluso dovrei includere solo o e ?

Se si utilizza un’ quadro correlata all’intestazione (ad esempio un tipo) in un file, è necessario includere l’intestazione correlata per esso. Non fare affidamento sulle intestazioni per includersi a vicenda. Se lo usi, includilo .

La libreria standard C ++ non richiede l’inclusione di in né viceversa. Cercare di utilizzare funzionalità come questa limiterebbe il codice a un’implementazione specifica. In generale, le intestazioni di libreria standard possono includere o meno altre intestazioni (o intestazioni interne) in un ordine o modo non specificato . Un’eccezione degna di nota è che è richiesta per essere inclusa in alcune delle altre intestazioni standard . Le modifiche a questo ordine o modo non specificato possono anche verificarsi, interrompendo in tal modo il codice precedentemente compilato con il compilatore aggiornato o un’implementazione aggiornata della libreria standard (è noto che ciò accada) .

Considera anche che se il file di intestazione è la definizione per la class, allora dovrebbe includere ciò che è richiesto per la definizione di quella class. Il file .cpp associato deve includere l’ .h Associato e i file rimanenti necessari per implementare la class. Non ne ha bisogno, non includerlo ; non includere più del necessario ( guida di stile llvm ). Un’eccezione qui sono i template (che non hanno un .cpp associato) ; questa eccezione si applicherebbe ad altre implementazioni di solo header.

Si noti che il mantenimento dell’inserimento di ciò che si usa può essere difficile a lungo termine; quindi ha senso che è importante all’inizio del ciclo di codifica includere ciò che è richiesto per l’interfaccia; e poi di nuovo per controllare l’include con qualsiasi modifica ragionevole apportata al codice.

Sembra che ci siano alcuni strumenti per il progresso in questo senso, come il progetto iwyu , che usa la catena di strumenti clang e sembra avere anche il supporto per msvc.

Un esempio di contatore sarebbe se il motivo dell’intestazione fosse includere altre intestazioni, quindi forse, ma anche in quel caso sarei molto attento – assicurati che sia chiaramente definito ciò che include. Un esempio di questo potrebbe essere un’intestazione precompilata.

In generale, dovresti trattare le dipendenze dell’intestazione come parte dell’implementazione, non come parte dell’interfaccia.

Non dovresti fare affidamento su intestazioni incluse altre intestazioni. Se la tua class ha bisogno di usare un std::vector include ; se hai bisogno di std::string , includi . Altrimenti ti prepari per guasti imprevisti quando le intestazioni che includevano un file smettevano improvvisamente di includerlo, perché non ne avevano più bisogno.