La leggibilità è un motivo valido per non utilizzare const nei parametri (di riferimento)?


24

Quando ho scritto alcune funzioni, ho trovato una parola chiave const in parametri come questo:

void MyClass::myFunction(const MyObject& obj,const string& s1,const string& s2,const string& s3){
}

spesso causa la divisione di una riga in 2 righe in IDE o vim, quindi desidero rimuovere tutte le parole chiave const nei parametri:

void MyClass::myFunction(MyObject& obj,string& s1,string& s2,string& s3){
} 

è un motivo valido per non usare const? È possibile mantenere gli oggetti parametro invariati manualmente?


110
"Ehi, voglio cambiare funzionalmente il mio programma" per renderlo più leggibile è una brutta ragione.
Pieter B,

37
Il programma non sta diventando più leggibile in ogni caso - Una volta che vedi qualcosa che viene consegnato perché consthai un forte suggerimento che non devi preoccuparti di come potrebbe essere cambiato nella funzione.
giovedì

43
Un modo migliore per migliorare la leggibilità è ridurre il numero di argomenti.
5gon12eder

15
'const' migliora probabilmente la leggibilità. Questa affermazione chiarisce che obj non può cambiare!
Charles,

14
Ciò che aiuterebbe la leggibilità è l'aggiunta di uno spazio dopo ogni virgola.
Sam Hocevar,

Risposte:


182

La leggibilità è un motivo valido per imparare a usare gli spazi bianchi:

void MyClass::myFunction(
        const MyObject& obj,
        const string& s1,
        const string& s2,
        const string& s3
) {
    return;
}

Posizionati laggiù i parametri non verranno confusi con il corpo della funzione. Individuandoli su una riga diversa non dovrai riposizionarli quando cambi il nome myFunctionin qualcosa di più descrittivo. Non cambiare la posizione dei parametri quando non sono cambiati è qualcosa che apprezzeranno gli utenti dello strumento diff di controllo del codice sorgente.

constsignifica qualcosa. Non buttarlo via solo perché sei a corto di spazio e idee. La leggibilità è re ma spezzare le cose nel suo nome è semplicemente rinunciare.


6
"non dovrai riposizionarli quando cambi il nome di myFunction" - anche se in questo caso sembra che siano stati posizionati in modo da allinearsi approssimativamente con l'apertura (, e in tal caso potresti dover riposizionare se la lunghezza del nome della classe + funzione cambia di più di circa 4 caratteri. Quindi, se si desidera non farlo, aggiungere un numero fisso di livelli di rientro, non un numero che dipende dalla lunghezza del nome della funzione. Vorrei raccomandare 1 livello, questa risposta utilizza 6, ma qualsiasi numero fisso raggiunge l'obiettivo dichiarato :-)
Steve Jessop

6
@CandiedOrange Sono sorpreso che non hai usato "form 6" in questa risposta ... è chiaramente meno brutto!
svidgen,

6
Modulo 6 per la vittoria. Un tabspace per un livello di rientro. Semplice ed efficace Problema risolto :)
Corse della leggerezza con Monica,

2
Ok ok modulo 6 lo è. Questa è la variante che JeffGrigg ha citato su c2.
candied_orange,

4
@ random832 Penso che ora siamo fermamente nel territorio del deposito biciclette. Ecco il modo corretto di risolverlo: cerca esempi nella tua base di codice, consulta la guida di stile del tuo negozio, chiedi agli sviluppatori nel tuo negozio e se nessuno di questi produce una risposta autorevole usa questo. Risolvi le controversie che potrebbero andare in entrambi i casi con un quarto. Una volta che il trimestre ha parlato, sii coerente!
candied_orange,

52

In realtà, il problema della leggibilità va decisamente nella direzione opposta. In primo luogo, è possibile risolvere banalmente la tua linea run-on utilizzando lo spazio bianco . Ma la rimozione constnon solo rende la linea più corta, ma modifica completamente il significato del programma.

Herb Sutter si riferisce al constriferimento a constcome il più importanteconst perché un riferimento a constpuò legarsi a un temporaneo e prolungarne la durata. Un riferimento al valore non- constimpossibile, è necessaria una variabile separata.

void foo_const(std::string const& );
void foo_nc(std::string& );

std::string some_getter();

foo_const(some_getter());      // OK
foo_const("Hello there"); // OK

foo_nc(some_getter()); // error
foo_nc("Nope");   // error

std::string x = some_getter(); // have to do this
foo_nc(x);                     // ok
std::string msg = "Really??";  // and this
foo_nc(msg);                   // ok

Ciò che ciò significa per usabilità è che dovrai introdurre tutte queste variabili temporanee solo per poter chiamare la tua funzione. Non è eccezionale per la leggibilità, poiché queste variabili sono prive di significato ed esistono solo perché la tua firma è sbagliata.


6
Il tuo secondo paragrafo mi fa venire il mal di testa nel tentativo di capire se si conststa riferendo consto all'altro conste qual constè davvero il più importanteconst
Mindwin,

3
@Mindwin Penso che l'ironia sia che il mio secondo paragrafo sia chiaro e inequivocabile, e non ho idea di cosa tu stia parlando.
Barry,

2
@Barry È certamente inequivocabile, ma mi ci sono volute alcune letture di quel paragrafo per cercare di capire cosa significasse. Penso che alcuni dei problemi siano che può essere analizzato "Herb Sutter si riferisce alla const (in riferimento a const) come la più importante const ..." o "Herb Sutter si riferisce a const in (riferimento a const) come il più const importante ... "Credo che quest'ultimo sia l'unico raggruppamento valido delle parole, ma ci vuole un po 'per elaborarlo. Forse c'è un modo per usare le virgolette per rimuovere l'ambiguità?
Cort Ammon - Ripristina Monica il

1
Penso che alcuni composti sillabati lo chiarirebbero.
shawnt00,

2
o usare specificamente const&anziché fare riferimento a constcome un nome (frase) lì
Caleth

21

La risposta semplice è "no".

La risposta lunga è che la constparola chiave fa parte del contratto offerto dalla funzione; ti dice che l'argomento non verrà modificato. Nel momento in cui rimuovi la constgaranzia, la finestra si spegne. Ricordate che non si può ragionevolmente mantenere la costanza (o qualsiasi altra proprietà) di qualcosa utilizzando documentazione, convegni, o linee guida - se la costanza non viene applicata dal compilatore, qualcuno si pensa che possano fare il loro lavoro più facile se si giocherellare con il parametro "solo un po '". Ritenere:

// parameter "foo" is not modified
void fna(Foo& foo);

void fnb(const Foo& foo);

A parte il fatto che quest'ultima versione è più concisa, fornisce anche un contratto più forte e consente al compilatore di aiutarti a mantenere le tue intenzioni. Il primo non fa nulla per impedire alla fna(Foo&)funzione di modificare il parametro che le viene passato.

Come nella risposta @CandiedOrange, è possibile utilizzare gli spazi bianchi per disporre il codice e migliorare la leggibilità.


14

La rimozione della constparola chiave rimuove la leggibilità perché constcomunica informazioni al lettore e al compilatore.
Ridurre la lunghezza orizzontale del codice è buono (a nessuno piace scorrere lateralmente) ma c'è di più constdel testo. Puoi riscriverlo:

typedef string str;
typedef MyObject MObj;
void MyClass::myFunction(const MObj& o,const str& s1,const str& s2,const str& s3)

Ciò non modifica il contratto ma soddisfa la necessità di ridurre la lunghezza della linea. Veramente considererei lo snippet di cui sopra meno leggibile e opterei per utilizzare più spazi bianchi come già menzionato nella risposta di CandiedOrange.

constè una funzionalità del codice stesso. Non renderebbe la funzione un non membro per rimuovere la MyClass::sezione della dichiarazione, quindi non rimuovere ilconst


4
Accetto che lo snippet fornito sia meno leggibile. Obbliga un lettore a scoprire cosa MObje cosa strsono e alza sicuramente le sopracciglia. È particolarmente strano per i tipi di cui hai già il controllo sui nomi: ad esempio, perché non hai semplicemente MyObjectdato un nome MObjall'inizio?
Jason C,

3

La leggibilità è un motivo valido per non utilizzare const nei parametri?

No. L'omissione constpuò modificare la funzionalità, perdere le protezioni conste potenzialmente creare codice meno efficiente.

È possibile mantenere gli oggetti parametro invariati manualmente?

Invece di dedicare tempo alla formulazione manuale del codice

void MyClass::myFunction(const MyObject& obj,const string& s1,const string& s2,const string& s3){
  //
}

Usa strumenti di formattazione automatica . Scrivi la funzione in base ai suoi requisiti funzionali e lascia che la formattazione automatica gestisca la presentazione. La regolazione manuale della formattazione non è efficiente come l'uso della formattazione automatica e l'utilizzo del tempo risparmiato per migliorare altri aspetti del codice.

void MyClass::myFunction(const MyObject& obj, const string& s1, const string& s2, 
    const string& s3) {
  // 
}

-1

Il più a lungo possibile è meglio mantenere const visibile. Migliora molto la manutenzione del codice (nessuna ipotesi per vedere se questo metodo cambia i miei argomenti).

Se vedo molti argomenti in un metodo, mi costringe a considerare la creazione di jaron basato sul progetto (Matrix, Employee, Rectangle, Account) che sarebbe molto più breve, più facile da capire (elimina un lungo elenco di argomenti ai metodi).


Concordato. Ero titubante nel sottolinearlo. Pertanto, "caso estremo".
blackpen,

@cmaster Detto questo, a volte in determinati contesti, con alcuni programmatori, potrebbe rimanere leggibile. Ad esempio, nel caso molto specifico di un programma a vita nelle chiamate API di Windows, con un lettore che è abituato a quell'ambiente, cose come ad esempio typedef Point * LPPOINTe typedef const Point * LPCPOINT, sebbene super odiose, hanno ancora un significato implicito, perché è coerente con le aspettative immediate nel contesto. Ma mai nel caso generale; è solo una strana eccezione a cui riesco a pensare.
Jason C,

1
Sì, quando ho visto la domanda, mi è venuto in mente "const unsigned long long int", ma non è un buon candidato trarre beneficio dall'essere "const" o "riferimento". Il typedef risolve il problema generale di abbreviare i nomi; ma non è una buona idea nascondere dietro lo scopo stesso dei costrutti del linguaggio (come "const").
blackpen,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.