Domanda

Sono un po 'confuso sul perché mi è stato detto di restituire const foo da un operatore binario in c ++ anziché solo foo.

Ho letto "Pensando in C ++" di Bruce Eckel, e nel capitolo sul sovraccarico dell'operatore, dice che "facendo il valore di ritorno [di un operatore binario con sovraccarico] const, tu affermare che è possibile chiamare solo una funzione membro const per quel valore di ritorno. Ciò è corretto, perché ti impedisce di archiviare informazioni potenzialmente preziose in un oggetto che molto probabilmente andranno perse " ;.

Tuttavia, se ho un operatore positivo che restituisce const e un operatore incremento prefisso, questo codice non è valido:

class Integer{
int i;

public:
    Integer(int ii): i(ii){ }
    Integer(Integer&);

    const Integer operator+();
    Integer operator++();
};


int main(){

Integer a(0);
Integer b(1);

Integer c( ++(a + b));
}

Per consentire questo tipo di assegnazione, non avrebbe senso che l'operatore + restituisca un valore non const? Questo potrebbe essere fatto aggiungendo const_casts, ma diventa piuttosto voluminoso, vero?

Grazie!

È stato utile?

Soluzione

Quando dici ++ x, stai dicendo " aggiungi 1 a x, memorizza il risultato in xe dimmi che cosa era " ;. Questo è l'operatore di preincremento. Ma, in ++ (a + b), come dovresti "salvare il risultato in a + b " ;?

Certamente potresti salvare il risultato nel temporaneo che attualmente contiene il risultato di a + b, che svanirebbe abbastanza presto. Ma se non ti importava davvero dove fosse archiviato il risultato, perché lo hai incrementato invece di aggiungerne solo uno?

Altri suggerimenti

FYI, ++ (a + b) è illegale anche con i POD (semplici vecchi tipi di dati, come int ). Quindi ha senso non consentirlo nemmeno per i tuoi tipi di classe. Prova questo:

int a = 1;
int b = 2;
int c = ++(a+b);

GCC restituisce l'errore : lvalue richiesto come operando di incremento .

Nel tuo caso, sarebbe preferibile che il tuo costruttore di copie prendesse un argomento const Integer e crea invece il tuo Integer c come questo:

Integer c(a + b + Integer(1));

I costruttori di copie di solito prendono un riferimento const , risolvendo il problema per te.

(Avere un copiatrice non const implica un trasferimento di risorse, che a volte può essere utile, ma per il 99% di tutte le situazioni, non è necessario)

Credo che l'esempio di OP sarebbe adatto alla domanda se l'operatore addizione viene sostituito con qualsiasi altro operatore binario che restituisce un riferimento, ad esempio un operatore di assegnazione:

Integer c( ++(a = b));

Sono venuto qui chiedendomi se il mio operatore di assegnazione dovrebbe restituire un riferimento const o non const. Alcuni tutorial usa versioni non costanti, contrariamente a "Pensare nei consigli di C ++". E alcuni altri riferimenti forniscono un ragionamento dietro ciò:

  

Si noti che il riferimento restituito non è dichiarato const. Questo può essere un po 'confuso, perché ti permette di scrivere cose folli come questa:

     
    

MyClass a, b, c;

         

...

         

(a = b) = c; // Cosa ??

  
     

A prima vista, potresti voler evitare situazioni come questa, avendo operator = restituisce un riferimento const. Tuttavia, affermazioni come questa funzioneranno con tipi primitivi. E, peggio ancora, alcuni strumenti si basano su questo comportamento. Pertanto, è importante restituire un riferimento non const dal proprio operatore =. La regola empirica è, "Se è abbastanza buono per gli ints, è abbastanza buono per i tipi di dati definiti dall'utente."

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