2010-06-12 11 views
5

Ho giocato con riferimenti (sto ancora avendo problemi al riguardo).Sto facendo qualcosa di sbagliato qui (riferimenti in C++)?

1- Vorrei sapere se questo è un codice accettabile:

int & foo(int &y) 
{ 
    return y; // is this wrong? 
} 

int main() 
{ 
    int x = 0;  
    cout << foo(x) << endl; 

    foo(x) = 9; // is this wrong? 
    cout << x << endl; 

    return 0; 
} 

2- Anche questo è da un campione di esame:

Week & Week::highestSalesWeek(Week aYear[52]) 
{ 
    Week max = aYear[0]; 
    for(int i = 1; i < 52; i++) 
    { 
    if (aYear[i].getSales() > max.getSales()) 
     max = aYear[i]; 
    } 
    return max; 
} 

Si chiede l'errore in questo codice , anche come risolverlo.

La mia ipotesi è che restituisca un riferimento locale. La correzione è:

Week & max = aYear[0]; 

È questo il corretto/abbastanza?

risposta

5

Il primo è corretto.

Per la seconda, ci sono infinite soluzioni :), ma questo sarebbe il mio:

Week Week::highestSalesWeek(Week aYear[52]) // return a copy of the week 
{ 
    Week max = aYear[0]; 
    for(int i = 1; i < 52; i++) 
    { 
    if (aYear[i].getSales() > max.getSales()) max = aYear[i]; 
    } 
    return max; 
} 

se Max è un riferimento, si dovrebbe modificare il primo elemento di ayear ogni volta che fate:

max = aYear[i] 

Inoltre, è possibile utilizzare un puntatore per restituire un riferimento alla settimana:

Week & Week::highestSalesWeek(Week aYear[52]) 
{ 
    Week* max = &aYear[0]; 
    for(int i = 1; i < 52; i++) 
    { 
    if (aYear[i].getSales() > max->getSales()) max = &aYear[i]; 
    } 
    return *max; 
} 
+1

Avevi ragione. Mi sono inchinato in modo vergognoso, lol – zildjohn01

+0

+1 per l'arco, ma non sono d'accordo leggermente: non c'è nulla di vergognoso nell'apprendimento. Non farai mai più quell'errore :-) – Thanatos

+0

Perché coinvolgere un puntatore? Un riferimento locale sembra preferibile. –

1

Per rispondere alle vostre domande:

foo(x) = 9; // is this wrong? 

Direi di sì, è sbagliato in quanto non ha senso anche se è sintatticamente valido. E per quanto riguarda la tua domanda "esame" (che chiede questa roba?):

Week & Week::highestSalesWeek(Week aYear[52]) 
{ 
    Week max = aYear[0]; 
    for(int i = 1; i < 52; i++) 
    { 
    if (aYear[i].getSales() > max.getSales()) max = aYear[i]; 
    } 
    return max; 
} 

Beh, fornendo la dimensione dell'array sul parametro è inutile, e il codice dovrebbe, ovviamente, utilizzare un vettore. E la correzione dovrebbe essere nella firma della funzione:

Week Week::highestSalesWeek(Week aYear[52]) 

In altre parole, restituire un valore. Si dovrebbero quasi sempre restituire valori anziché riferimenti: i riferimenti sono destinati ai parametri di funzione.

+0

I riferimenti come tipi di ritorno sono utili quando si esegue il overloading dell'operatore '[]';) – fredoverflow

+0

@Fred Naturalmente - è per questo che ho detto "quasi sempre". Nel caso degli utenti farlo è inutile. –

+0

E overloading 'operator =' anche, ma per essere onesti, non mi piace usare l'assegnazione come espressione. – fredoverflow

2

La cosa importante dei riferimenti è sempre fare in modo che il riferimento non sia un oggetto che è andato fuori campo.

Questo è il problema con il secondo esempio:

Week & Week::highestSalesWeek(Week aYear[52]) 
{ 
    Week max = aYear[0]; 
    return max; 
} 

max è una variabile automatica locale per quel metodo. Quando questo metodo non rientra nel suo ambito, max esce dal campo di applicazione e ora il tuo codice ha un riferimento alla memoria casuale.

Poiché il codice desidera continuare a riassegnare max, non è possibile utilizzare un riferimento (poiché dopo l'assegnazione iniziale, è possibile modificare solo ciò a cui si fa riferimento, non il riferimento stesso). È necessario tenere traccia della parte effettiva di aYear a cui si desidera restituire un riferimento. Due suggerimenti

// By pointer 
Week & Week::highestSalesWeek(Week aYear[52]) 
{ 
    Week *max = &aYear[0]; 
    ...; 
    return *max; 
} 

// By index 
Week & Week::highestSalesWeek(Week aYear[52]) 
{ 
    size_t max_idx = 0;; 
    ...; 
    return aYear[max_idx]; 
}  
Problemi correlati