Quando scrivi C ++, non scriverlo come se fosse Python o D o Java. Quelli sono lingue fondamentalmente diverse con idiomi diversi .
Quando parliamo di funzioni inline in C ++, dobbiamo distinguere due concetti correlati ma distinti:
-
inline
funzioni in un'intestazione. Le definizioni di funzione all'interno di una dichiarazione di classe sono implicitamente inline
. I modelli sono solitamente in linea.
Una funzione inline
(o variabile) disabilita efficacemente one-definition rule (ODR) : se il linker vede più definizioni in conflitto per la stessa funzione in diverse unità di compilazione, il linker di solito mostra un errore Ma con le funzioni inline
, prometti che tutte le definizioni sono identiche. Inoltre, una funzione inline può essere chiamata solo dalla stessa unità di compilazione in cui è stata definita.
-
inlining come ottimizzazione del compilatore. La semantica di una funzione inline
rende inlining possibile , ma la parola chiave inline
non implica che una funzione sarà inline. Ad esempio, una funzione membro definita in linea non può essere sottolineata tramite chiamate indirette, ad esempio chiamate virtuali.
-
Puoi rendere inlining di funzioni non- inline
dando loro linkage interno , tramite la parola chiave static
per funzioni / variabili libere (ma non membri!) o tramite l'uso di uno spazio dei nomi anonimo.
-
È possibile utilizzare attributi specifici del compilatore. Ad esempio, __attribute__ ((always_inline))
in GCC .
Non è consigliabile definire tutte le funzioni in linea in un'intestazione.
-
Questo rallenta tempi di compilazione . Usando più unità di compilazione puoi beneficiare della compilazione incrementale . Ciò rende più piacevole il lavoro su tutti i progetti C ++ più banali. Ma se metti codice non necessario nell'intestazione, deve essere analizzato, compilato e ottimizzato nella sua interezza ogni volta. Poiché i modelli generalmente implicano definizioni incorporate in un'intestazione, questi tempi di compilazione sono una ragione per cui alcuni progetti cercano di limitare l'utilizzo dei modelli.
-
Porta a inquinamento dello spazio dei nomi e a mancanza di incapsulamento . Un sacco di codice tende ad aver bisogno di alcuni assistenti privati. In Python aggiungerei una funzione di sottolineatura al modulo, in C ++ una funzione statica o un codice in uno spazio dei nomi anonimo, in modo che siano limitati all'unità di compilazione corrente. Ma quando tutto è nelle intestazioni, hai solo una singola unità di compilazione. Tutti questi helper saranno visibili a tutto il tuo codice e in effetti non hai una struttura interna. Ciò potrebbe anche portare a conflitti di nomi.
-
Inoltre, considera in che modo includi intestazioni . Nella normale divisione di intestazione-implementazione, le intestazioni che sono necessarie solo internamente ma non per l'interfaccia pubblica del modulo possono essere incluse nel file .cpp. Ciò limita gli effetti di tale intestazione, ad esempio con qualsiasi macro o funzione globale. Questo è particolarmente importante quando si interfaccia con le librerie C. Ciò consentirà anche il collegamento tra le librerie che forniscono nomi in conflitto. Non così quando tutto il codice è nell'intestazione. Tutte le definizioni incluse saranno anche visibili in tutte le unità di compilazione in cui è inclusa l'intestazione.
-
Le definizioni in linea funzionano solo quando le tue dipendenze possono essere linearizzate, ma ad es. non per le dipendenze circolari o ricorsive (come una classe che rappresenta un nodo ad albero). Anche se si inserisce il codice in un'intestazione, potrebbe essere necessario utilizzare le dichiarazioni anticipate o definire un metodo al di fuori della dichiarazione della classe. Se questo metodo non deve essere inline
, non ottieni nulla dal definirlo nell'intestazione.
Se non ti piace dover scambiare spesso intestazioni e file di implementazione, ti suggerisco di utilizzare un IDE che ti consenta di passare più facilmente tra le dichiarazioni e le definizioni corrispondenti.
Sì, C / C ++ può essere una lingua super fastidiosa con tutto il loro storico cruft. E sì, il codice Java tende ad essere più piacevole da leggere.
Ma non otterrai alcun beneficio dal provare a scrivere in C ++ come se fosse Java. Stavi semplicemente rinunciando ai benefici che C ++ può offrire. Allo stesso modo, il C ++ moderno evita la creazione di oggetti con new
, dato che effettivamente abbandona RAII.