Domanda

So che ci sono pochi domanda circa const correttezza in cui si afferma che la dichiarazione di una funzione e la sua definizione non hanno bisogno di essere d'accordo per i parametri di valore. Questo perché la costanza di un parametro di valore importa solo all'interno della funzione. Questo va bene:

// header
int func(int i);

// cpp
int func(const int i) {
    return i;
}

sta facendo questo in realtà una buona pratica? Perché non ho mai visto nessuno farlo. Ho visto questa citazione (non sono sicuro della fonte) in altri luoghi questo è stato discusso:

  

"In effetti, per il compilatore, la firma della funzione è lo stesso se si include questa const davanti a un parametro di valore o meno".

     

"Evita parametri const pass-by-valore nelle dichiarazioni di funzione. Ancora fare il parametro const nella definizione stessa della funzione, se non verrà modificato."

Il secondo comma dice di non mettere il const nella dichiarazione. Presumo questo è perché la costanza di un parametro di valore è privo di significato come parte di una definizione di interfaccia. Si tratta di un dettaglio di implementazione.

In base a questa raccomandazione, si è consigliato anche per i valori di puntatore di parametri pointer? (Non ha senso su un parametro di riferimento dal momento che non è possibile riassegnare un riferimento.)

// header
int func1(int* i);
int func2(int* i);

// cpp
int func1(int* i) {
    int x = 0;

    *i = 3; // compiles without error
    i = &x; // compiles without error

    return *i;
}
int func2(int* const i) {
    int x = 0;

    *i = 3; // compiles without error
    i = &x; // compile error

    return *i;
}

Riepilogo: Fare parametri di valore è utile per la cattura di alcuni errori di logica. E 'una buona pratica? Non si va alle estreme conseguenze di lasciare il const fuori del file di intestazione? E 'altrettanto utile per i valori di puntatore const? Perché o perché no?

Alcune referenze:

C ++ const parola chiave -? Usare liberamente L'utilizzo di 'const' per i parametri di funzione

Un esempio di quando parametri di valore const sono utili:

bool are_ints_equal(const int i, const int j) {
    if (i = j) { // without the consts this would compile without error
        return true;
    } else {
        return false;
    }
    // return i = j; // I know it can be shortened
}
È stato utile?

Soluzione

Il mio prendere su di esso:

Non è una cattiva idea, ma il problema è minore e la vostra energia potrebbe essere meglio spesi per altre cose.

Nella tua domanda ha fornito un buon esempio di quando potrebbe prendere un errore, ma a volte anche finire per fare qualcosa di simile:

void foo(const int count ...)
{
   int temp = count;  // can't modify count, so we need a copy of it
   ++temp;

   /* ... */
}

I pro ei contro sono minori in entrambi i casi.

Altri suggerimenti

Ho letto molte volte che, per rendere i parametri di valore in una funzione const è una cattiva cosa da fare, perché è inutile.

Tuttavia, trovo a volte utile per me come un controllo che la mia applicazione non fa qualcosa che io non intendo (come nell'esempio alla fine della tua domanda).

Così, mentre non può aggiungere valore al chiamante, lo fa a volte aggiungere un po 'piccolo di valore per me come realizzatore, e non toglie nulla al chiamante. Quindi non vedo nulla di male ad usarlo.

Per esempio, posso essere attuazione di una funzione C che prende un paio di puntatori a un buffer - un puntatore all'inizio, e un puntatore alla fine. Ho intenzione di inserire i dati nel buffer, ma vuole garantire che non invadere il finale. Così all'interno della funzione non c'è codice che incrementare un puntatore come sto aggiungendo i dati ad esso. Rendere il puntatore alla fine del buffer un parametro const farà in modo che io non codificare fino un bug che incrementa accidentalmente il puntatore di confine fine al posto del puntatore che in realtà dovrebbe essere l'incremento.

Quindi, una funzione FillArray con una firma in questo modo:

size_t fillArray( data_t* pStart, data_t* const pEnd);

mi impedirà di incrementare accidentalmente pEnd quando ho davvero intenzione di incrementare pStart. Non è una cosa enorme, ma sono abbastanza sicuro che tutti coloro che hanno programmato per qualsiasi periodo di tempo in C si è imbattuto in un tale errore.

Purtroppo, alcuni compilatori (sto guardando a voi, Sun CC!) Si differenziano in modo non corretto tra gli argomenti dichiarati const e quelli non dichiarati così, e si può ottenere gli errori sulle funzioni non definite.

Credo che questo dipende dal vostro stile personale.

Non aggiungere o sottrarre a ciò che i clienti possono passare alla funzione. In sostanza è come un'asserzione di compilazione. Se ti aiuta a sapere che il valore non cambierà, andare avanti e farlo, ma non vedo un grande motivo per gli altri a farlo.

Una ragione potrei non farlo è che il const-ness del parametro valore è un dettaglio di implementazione che i vostri clienti non hanno bisogno di conoscere. Se in seguito (volutamente) cambia la funzione in modo che in realtà non cambia questo valore, è necessario modificare la firma della funzione, che costringerà i vostri clienti a ri-compilazione.

Questo è simile al motivo per cui alcune persone consigliamo di non avere metodi virtuali pubblici (le funzioni virtual-ness è un dettaglio di implementazione che dovrebbe essere nascosto da parte dei clienti), ma non sono in quel particolare campo.

Se non è const parola chiave presente; significa valore 'i' (che è di tipo const) non possono essere modificati. Se il valore di 'i' è cambiato all'interno funzione foo compilatore gettare errore: "

  

Non è possibile modificare l'oggetto const

Ma cambiare '* i' (vale a dire * i = 3;) significa che non sta modificando il valore di 'i', ma il valore di indirizzo puntato da 'i'

In realtà, la funzione const è appropriata per oggetti di grandi dimensioni che non devono essere alterati dalla funzione.

Tutti dobbiamo sbrogliare qualcun altro codice C ++ di tanto in tanto. E che il codice di qualcun altro C ++ è un disastro completo per definizione:. D

Quindi la prima cosa che faccio sempre a decifrarlo (flusso di dati locale e globale) viene messo const in ogni definizione della variabile fino compilatore si lamenta. Questo significa anche argomenti di valore const-qualificazione, e aiuta davvero evitando le variabili che sono stati modificati in mezzo sulla funzione senza di me se ne accorga ...

Così ho davvero apprezzare quando quel qualcun altro ha const ovunque (inclusi i parametri di valore): D

Mi piace const correttezza per situazioni come questa:
void foo(const Bar &b) //I know b cannot be changed
{
//do something with b
}

Questo mi permette di utilizzare b senza timore di modificarlo, ma non devono pagare il costo di un costruttore di copia.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top