puntatori non opzionali e riferimenti non costanti in C ++

10

In Altre caratteristiche del C ++, argomenti di riferimento del Google C ++ Style Guide , ho letto che i riferimenti non const non devono essere utilizzati.

All parameters passed by reference must be labeled const.

È chiaro che guardare le chiamate di funzione che usano riferimenti come argomenti è assolutamente confuso per i programmatori C, ma C e C ++ sono lingue diverse ora. Se un parametro di output è richiesto , utilizzando un puntatore per un parametro di output richiesto, è possibile saltare l'intero corpo della funzione, il che rende più complicata l'implementazione di una funzione (aumenta formalmente il ciclomatic complessità e profondità di una funzione).

Mi piacerebbe rendere il codice C ++ più facile da capire / mantenere possibile, quindi sono generalmente interessato a leggere le guide di stile di codifica. Ma per adattare le migliori pratiche di un team, penso che comprendere la logica dietro gli elementi di guida dello stile sia un fattore importante.

I riferimenti non const sono davvero così brutti? li sta escludendo solo da Google o è una regola comunemente accettata? Cosa giustifica lo sforzo extra per l'implementazione dei parametri di output come puntatori?

    
posta Wolf 05.10.2015 - 11:37
fonte

3 risposte

11

La logica alla base della guida di stile di Google è semplicemente quella di chiarire dal sito di chiamata di una funzione se un parametro è un parametro di input o un parametro di output. (Per ulteriori informazioni, consulta .) Altri linguaggi definiscono i parametri esplicitamente in base alla progettazione; C #, ad esempio, ha una parola chiave out che deve essere utilizzata nel sito di chiamata . Dal momento che C ++ non lo rende esplicito, Google ha scelto di usare const ref. contro puntatore per chiarire.

Questa è solo una regola di Google? No, ma dubito che sia molto diffuso. Non penso di averlo visto al di fuori della guida e dei gruppi di stile di Google che aderiscono esplicitamente a parti della guida di stile di Google. (Ad esempio, mi è piaciuta l'idea quando ho letto per la prima volta la guida allo stile di Google anni fa e l'ho usata per un po 'del mio codice.)

In particolare, il nuovo annuncio C ++ Code Guidelines preferisce i valori di ritorno ai parametri di output per (quasi) tutto e usa i ref non-cost per il resto. L'uso di Google di puntatori contro riferimenti potrebbe rendere più chiari i parametri di output, ma i valori di ritorno sono ancora più chiari. Ora che C ++ 11 ha mosse standardizzate (riferimenti rvalue, && , per rendere ritorni di molti tipi a buon mercato) e tuple (consentendo un modo semplice per restituire più valori), molti dei casi d'uso per i parametri out non si applicano più.

Le linee guida C ++ Core hanno dietro di sé alcuni grandi nomi (Bjarne Stroustrup, Herb Sutter), sono supportate da Microsoft e includono le ultime funzionalità C ++ (diversamente dalla guida di stile di Google), quindi mi aspetto che i suoi consigli siano più popolari di quelli di Google .

    
risposta data 05.10.2015 - 15:26
fonte
1

Ci sono 2 opzioni per gestire un puntatore non valido passato, primo controllo e ritorno anticipato o lasciare che sia un comportamento indefinito (se ti interessa più della velocità che della robustezza).

Il controllo è semplice come:

void foo(void* buffer){
    if(buffer == nullptr)
        return;

    //actually foo

    // note no increase in indentation required

}

Questo tipo di controllo è generalmente accettato come controllo dei parametri. Se vedi il codice è abbastanza chiaro che ti aspetti che venga passato un puntatore non nullo e che restituisca presto se no. Ciò ti consente di non preoccuparti tanto dei puntatori non validi.

    
risposta data 05.10.2015 - 12:01
fonte
1

Dipende dalla tua osservazione If an output parameter is required .

L'unico posto in cui è richiesta una firma di funzione per avere un parametro di output è quando viene specificato da un'API esterna e, in tal caso, si avvolge semplicemente l'API esterna in qualcosa che assicuri che ci sia sempre un punto morto valido.

Internamente si evitano i parametri di output estendendo il tipo di ritorno in modo da essere un composto di tutti gli "out"

    
risposta data 05.10.2015 - 12:09
fonte

Leggi altre domande sui tag