In C / C ++, dovrei usare 'const' nei parametri e nelle variabili locali quando possibile?

8

Questa domanda è ispirata da una domanda su final in java .

In C / C ++, dovrei usare const quando possibile?

So che esiste già una domanda correlata sull'utilizzo di const nei parametri . Sfortunatamente quella domanda e le sue risposte non rispondono completamente alla mia domanda, perché riguarda solo i parametri di funzione, ma vorrei anche conoscere altri casi (ad esempio: variabili locali).

Inoltre, quasi tutte le risposte a questa domanda dicono che dovremmo usare const perché contiene informazioni utili sull'accessibilità delle variabili. Ma questo sembra essere in conflitto con una risposta sull'uso finale in Java che afferma che final potrebbe essere superfluo se non lo fa Contiene informazioni aggiuntive e quindi dovrebbe essere omesso per mantenere il codice breve e pulito.

Quindi, dovrei usare const quando possibile? In tal caso, perché il consiglio per const in C ++ è diverso dal consiglio per final in Java?

    
posta mmmaaa 05.10.2016 - 04:32
fonte

4 risposte

14

Prima di tutto, dal momento che hai fatto riferimento a% di% co_de di Java, si tratta di una bestia completamente diversa da final . Finale significa che il riferimento non può cambiare, ma non dice nulla sulla mutabilità. Const va oltre dicendo "un riferimento const non può mutare" che è una garanzia molto più strong. Per fare ciò in Java, lo stato interno deve essere definitivo e determinato al momento della costruzione. Const è molto più facile da usare e un oggetto esistente può essere "promosso" in un riferimento const.

Sì, dovresti usare const ogni volta che è possibile. Fa un contratto che il tuo codice non cambierà qualcosa. Ricorda, una variabile non const può essere passata a una funzione che accetta un parametro const. Puoi sempre aggiungere const, ma non portarlo via (non senza un const cast che è una pessima idea).

La correttezza di Const può essere noiosa a volte, ma aiuta a garantire l'immutabilità. Questo è fondamentale nel codice multi-thread in cui i thread condividono gli oggetti. Rende certe attività più efficienti: invece di copiare lo stato, riutilizzare lo stesso oggetto immutabile. Le librerie possono accettare parametri const per garantire al programmatore che no, il tuo oggetto non cambierà in modo imprevedibile nel buco nero che è l'intestino della biblioteca.

    
risposta data 05.10.2016 - 04:41
fonte
4

Non sono d'accordo con gli altri poster e raccomando non di utilizzare const di primo livello su variabili e parametri locali. (I riferimenti e i puntatori a const, cioè const T& , sono diversi e dovresti usarli per la correttezza in ogni momento quando è appropriato.)

I vantaggi del const di primo livello sono:

  • Rende chiaro che le variabili locali non sono destinate a essere mutate.
  • Segnala un errore del compilatore se accidentalmente tenti di mutarle.

Gli svantaggi sono:

  • Disordine visivo.
  • Non può essere usato su variabili "pseudo-const", cioè variabili inizializzate in qualche modo più complicate della costruzione diretta, ma non modificate dopo, ad es. utilizzando getline :

    std::string line; // cannot be const
    std::getline(std::cin, line);
    // line should be const from here on out
    
  • Impedisce l'ottimizzazione del movimento verso l'esterno su chiamata di funzione e ritorno:

    std::string f1();
    std::string f2(std::string s);
    std::string f3() {
      const std::string s = f1(); // s is not meant to be modified
      // but I still want the move optimization here:
      const std::string result = f2(std::move(s)); // this doesn't move
      // and I want the compiler to move out here:
      return result; // this will probably RVO, but if not, the move
                     // constructor will not be used due to the const
    }
    

Ho lavorato su una base di codice in cui è stato utilizzato molto%% locale% e non l'ho trovato affatto utile, tuttavia ha riempito il codice con pessimizzazioni sottili come sopra. Personalmente preferisco adottare una politica generale di modifica delle variabili il più raramente possibile e rendere le funzioni abbastanza piccole da rendere ovvio l'uso di una variabile, e anche se viene modificata, la complessità della funzione è abbastanza bassa da renderla non -emissione.

    
risposta data 05.10.2016 - 11:03
fonte
3

Personalmente, const mi richiede pochissimo tempo per scrivere, e pochissimo tempo per leggere, in genere molto meno di quanto ci vuole per verificare se un codice muta la variabile, e in realtà mi impedisce di scrivere bug (chiunque mai incrementato il loro fine iteratore per caso? Etc)

Inoltre, trovo che essere severi sull'uso const mi guidi verso un codice migliore in altri modi, come creare funzioni di supporto per un'inizializzazione non banale.

    
risposta data 05.10.2016 - 05:53
fonte
1

La parola chiave const deve essere utilizzata per le variabili locali, proprio come i parametri. È utile perché:

  • Più facile leggere il codice. Quando qualcuno legge la dichiarazione delle variabili, sa che non cambierà. Una cosa in meno è preoccuparti mentre leggi il tuo codice.
  • Impedisci di modificare accidentalmente la variabile
  • Nessuna penalità di runtime, tutto viene controllato staticamente. È come un pranzo gratis, const dovrebbe richiedere solo un secondo per scrivere, quindi non è un grosso problema.
  • È sempre una buona idea rendere le tue variabili / parametri nelle tue applicazioni multi-thread. Anche la tua applicazione non è multi-thread, è comunque una buona abitudine.
  • Dai un'opportunità al tuo compilatore C ++ di ottimizzare il tuo codice.

Nota che non c'è una risposta giusta / sbagliata qui. Nel tuo link, il rispondente che ha avuto il maggior numero di voti argomentati final non deve essere utilizzato localmente. Tuttavia, il prossimo rispondente lo ha strongmente raccomandato.

Se la tua funzione è semplice e banale , non devi aggiungere const perché tutti comprendono la tua intenzione. Tuttavia, se la logica della tua funzione non è banale, dovresti usare la parola chiave. Ricorda, c'è poco da perdere.

    
risposta data 05.10.2016 - 06:07
fonte

Leggi altre domande sui tag