2010-06-01 11 views
5

Solo curioso sul perché un parametro deve essere un const in funzione sovraccaricoPerché devi fornire la parola chiave const in operatore sovraccarica

CVector& CVector::operator= (const CVector& param) 
{ 
    x=param.x; 
    y=param.y; 
    return *this; 
} 

Non avresti potuto facilmente fatto qualcosa di simile ??

CVector& CVector::operator= (CVector& param) //no const 
{ 
    x=param.x; 
    y=param.y; 
    return *this; 
} 

non è quando qualcosa diventa un const, che è immutabile per il resto della vita applicazioni ?? In che modo questo differisce nell'operazione di sovraccarico ???

risposta

2

Un parametro const è const in tutta la funzione di usarlo, ma non cambia la sua costanza al di fuori di esso.

In questo caso si desidera dichiarare un argomento const in modo che l'operatore di assegnazione accetti sia le variabili non const sia le variabili const; quest'ultimo caso, in particolare, include il risultato di espressioni, che è una variabile const temporanea e che generalmente si desidera supportare in compiti.

+0

O, stai dicendo che g = (a + b * c) il risultato sul lato destro è considerato una costante ?? Quando dici che un const è solo un const all'interno della funzione. Stai dicendo che una volta che la funzione è stata completata? Quei valori potranno essere cambiati di nuovo ?? – numerical25

+0

Sai cosa. Ha senso ora. Se lancio un valore const in una variabile. che non rende la variabile un const, significa solo che ora contiene il valore del const che può essere modificato – numerical25

+0

@numerical, tieni presente che l'idea funziona solo come quello che hai menzionato se è pass-by-reference. – YeenFei

8

Non è necessario const:

@ numerical25: Solo curioso sul perché un parametro deve essere un const in funzione sovraccarico

Non è necessario, ma è una buona decisione di progettazione.

Vedere la ++ C Sezione di serie 12,8-9:

Un assegnamento per copia operatore X :: operator user-dichiarata = è un non-statica funzione membro non template di classe X con esattamente un parametro di tipo X, X &, const X &, volatile X & o const volatili X &


penso che sia una buona idea, però:

utilizzando un parametro const fa sembra una decisione di progettazione logico per me, però, perché si vuole garantire che l'altro valore non verrà modificato.

Racconta altre persone che utilizzano la classe che non sarà la modifica del valore other quando si dice qualcosa come: myObject = other; ed impone questo modo non è possibile cambiare accidentalmente other.

Inoltre, se è consentito il riferimento non const dell'oggetto come parametro, si limiterà la quantità di oggetti che possono utilizzare la funzione. Se è const, può essere utilizzato per i parametri const e non const. Se il parametro non è const, può essere utilizzato solo da parametri non const.


const si applica solo al riferimento di corrente, non l'oggetto:

@ numerical25: Non è quando qualcosa diventa un const, che è immutabile per il resto della vita delle applicazioni? ? In che modo questo differisce nell'operazione di sovraccarico ???

Un riferimento const è semplicemente un riferimento che è const. Non cambia la costanza dell'oggetto reale che stai passando.


Un esempio di non-const Ridefinizione dell'operatore:

Ecco un esempio di operatore sovraccarico in cui il parametro non è const.
Non consiglio di fare questo però:

class B 
{ 
public: 
const B& operator=(B& other) 
{ 
    other.x = 3; 
    x = other.x; 
    return *this; 
} 

int x; 
}; 


void main(int argc, char** argv[]) 
{ 
B a; 
a.x = 33; 
B b; 
b.x = 44; 
a = b;//both a and b will be changed 
return 0; 
} 
+2

Ed è 'const' per l'ambito della dichiarazione, non la vita dell'applicazione. – CuppM

+0

@CuppM: Sì implicito poiché anche l'intera variabile di riferimento non è più disponibile. Però non cambia la costanza dell'oggetto originale durante il suo scopo. Ad esempio se hai 2 thread. –

1

se è stato utilizzato

CVector& CVector::operator= (CVector& param) // no const 

poi ha fatto questo:

const CVector& my_vector = GetMyVector(); 
some_other_vector = my_vector; // call assignment operator - error! 

Si otterrà un errore perché my_vector è un const CVector& e che non può essere gettato in una CVector& (non-const riferimento). È solo il riferimento locale ad esso all'interno della funzione operator= che è const, non l'intero oggetto stesso.

0

Per lo stesso motivo si usa const ovunque: al fine di garantire che le future modifiche al metodo di non inavvertitamente modificare il passato nel parametro, per aiutare documento l'interfaccia per informare i chiamanti che è sicuro di passare param senza il rischio di cambia e consente ai chiamanti di passare in riferimenti dichiarati come const nel codice chiamante.

1

È possibile utilizzare la varietà non const, ma questo ha due ripercussioni, una che è funzionale, e una che riguarda ciò che voi, come lo scrittore della funzione, state dicendo all'utente.

1) le persone che chiedono la funzione che prende un riferimento non-const non sarebbe in grado di chiamare utilizzando una variabile const

2) quando si dispone di un argomento di funzione che è un punto di riferimento non-const, sei segnalazione, "Mi riservo il diritto di cambiare questo". In genere, quando un utente della funzione scrive a = b ;, non si aspetta che cambi b.

Si noti che c'è una terza opzione è possibile utilizzare per questo, pass-by-value:

CVector& CVector::operator= (CVector param) //no reference 

Questo non ha nessuno dei problemi che ho citato sopra. Tuttavia, è molto inefficiente. A causa di questi tre fattori, è preferibile passare per riferimento a const, soprattutto in casi come un vettore in cui la copia può essere costosa.

0

Un altro motivo è consentire le conversioni. Ad esempio:

string s = "foo"; 
s = "bar"; 

Qui, un'implementazione potrebbe scegliere di fornire solo l'operatore di assegnamento che accetta un riferimento const ad una stringa come parametro, e dipendono dal compilatore utilizzando un costruttore per creare una stringa temporanea dal char * "barra". Ciò non funzionerebbe se il parametro op = 'non fosse const, poiché non è possibile associare un riferimento temporaneo a un riferimento non const.

0

Il qualificatore di cost esegue il parametro passato (nell'esempio è "const CVector & param") in sola lettura. Il qualificatore const garantisce che il parametro (param) non sia alterato all'interno del metodo operator =().

Senza il qualificatore const, sono possibili le seguenti:

CVector& CVector::operator= (CVector& param) 
{ 
    x=param.x; 
    y=param.y; 

    param.x = 10; // some random value 
    param.y = 100; 

    return *this; 
} 

Il metodo sopra altera i destri operando laterali 'param' dopo l'assegnazione del valore all'operando sinistra. Il qualificatore const ti aiuta a non violare la semantica dell'operazione di assegnazione.

Problemi correlati