Se non è richiesto #include aggiuntivo, "questo metodo non deve essere modificato" una buona ragione per definire un metodo in .h?

3

Supponiamo che stia sviluppando applicazioni mobili usando C ++, e ho trovato che alcuni metodi non dovrebbero cambiare una volta scritti, ad esempio:

class MyClass{
public:
    float kmHrToms(float kmHr){
        return kmHr/3.6;
    }

    std::string toString(){
        return "this class is used to...";
    }

    .
    .
    .
}

e questi metodi non richiederebbero #include aggiuntivi quando vengono spostati da .cpp a .h, è una buona idea spostare questi metodi da .cpp a .h? Penso che i vantaggi siano:

  1. Chiaramente dice agli altri membri del team che quei metodi non dovrebbero cambiare

  2. I membri del team di solito cambiano .cpp ma non .h, e quindi è meno probabile che cambino i metodi in .h per errore, il che si adatta in modo più semplice a principi aperti

  3. Anche i metodi in .h vengono modificati accidentalmente, l'improvviso cambiamento del tempo di compilazione può avvisare i programmatori che potrebbero cambiare qualcosa che non dovrebbe cambiare

  4. Normalmente i programmatori trascorrono più tempo su .cpp che su .h, spostando alcuni codici su .h puoi ridurre il numero di codici in .cpp, il che rende il file .cpp più gestibile

è vero?

    
posta ggrr 03.02.2017 - 07:19
fonte

2 risposte

4

In genere si considera che la pratica cattiva includa il codice eseguibile nei file .h / .hpp , alcuni dei motivi sono:

  • Se utilizzi un build di tipo make puoi finire con diverse versioni del codice in diversi file / librerie di oggetti.
  • Ogni file oggetto avrà il codice eseguibile, questo porta a gonfiare.
  • Ovunque l'inclusione abbia luogo avrà una copia del codice eseguibile anche se non è eseguito e il codice irraggiungibile mostrerà risultati di copertura scadenti.
  • Le persone non si aspettano che il codice sia presente e ciò può ridurre la manutenibilità.
  • Se si utilizza uno strumento di analisi statica basato su standard, è probabile che il codice non funzioni.

L'unica volta in cui normalmente inseriresti il codice in file includerebbe il piccolo , la velocità critica, il codice "in linea".

Se il codice non dovrebbe essere toccato, usa:

  • Standard di codifica
  • Convenzioni di denominazione per file / sezioni di codice
  • Cancella commenti
  • Il controllo della versione blocca i file
  • Pre-commit dei filtri
  • Tutti i precedenti
risposta data 03.02.2017 - 07:56
fonte
0

Il codice in un file di intestazione descrive un'interfaccia - i tipi e le funzioni che la tua unità di compilazione espone. Tutto ciò che è necessario per descrivere questa interfaccia dovrebbe essere nell'intestazione. I dettagli di implementazione non appartengono all'intestazione, perché i dettagli dell'implementazione non fanno parte dell'interfaccia.

Quindi, se l'implementazione di queste funzioni è parte del loro contratto pubblico (necessariamente per i modelli), quindi sicuro, lasciatele nell'intestazione. Se una funzione è così banale che esiste una sola possibile implementazione e vuoi che sia in linea, vai avanti. Un esempio potrebbe essere un metodo getter di un oggetto che restituisce solo un campo privato.

Ma nella maggior parte dei casi, anche le funzioni semplici dovrebbero essere mantenute nel file .cpp. Questa è davvero una struttura migliore per il tuo codice e, come bonus aggiuntivo, migliora i tempi di compilazione.

In effetti, le intestazioni spesso includono troppi dettagli di implementazione. Ci sono strategie come l'idioma pimpl per evitare di rendere troppi dettagli (come i membri privati) esternamente visibili. Questo è estremamente importante in una libreria che deve mantenere un'interfaccia binaria specifica, un po 'meno in un'applicazione. In ogni caso, mantenere i file di intestazione minimi è più conveniente e utile.

Se vuoi assicurarti che una funzione scritta una volta non cambi il suo comportamento, la soluzione corretta non è di impedirne la modifica. Invece, scrivi test unitari per garantire le proprietà del comportamento che ti interessa. Quando qualcuno rimuove le funzioni o modifica il suo comportamento in modo incompatibile, il test si interromperà e ti avviserà di questo problema. Nessuno può ricordare che cosa dovrebbe fare esattamente ogni parte della tua base di codice, quindi annotare e automatizzare questa conoscenza con una suite di test unitari è un ottimo modo per prevenire errori costosi in seguito.

Vorrei anche sottolineare che stai cercando di risolvere un problema di persone (altri programmatori potrebbero rompere accidentalmente il codice modificando questa funzione) nascondendo il problema (inseriamo il codice dove nessuno lo vede). Questo non risolve il tuo problema, lo mescola solo in giro. Una soluzione migliore è parlare con il team in modo da poter raggiungere un consenso (siamo d'accordo che alcune funzioni non devono essere modificate) e concordare una soluzione comune come parte delle convenzioni di codifica (ad esempio "metodi stabili che non dovrebbero essere modificati con un commento // stable - do not change ").

    
risposta data 03.02.2017 - 11:14
fonte

Leggi altre domande sui tag