2015-06-19 23 views
5

So che questo problema è stato discusso più volte, ma non sono riuscito a trovare un post che spieghi perché è necessario eseguire una copia in caso di operazione di incremento.Perché post-incremento è necessario eseguire una copia mentre pre-incremento non è

Citando una risposta StackOverflow:

int j = i++; // j will contain i, i will be incremented. 
int j = ++i; // i will be incremented, and j will contain i+1. 

Il che rende perfettamente senso quando si considera la definizione di post/pre incremento. Molte volte confrontando le prestazioni di incremento pre/post si dice che l'incremento post deve fare una copia, incrementarlo e restituire la copia mentre il pre-incremento aumenta semplicemente il valore e non crea una copia.

Sebbene le prestazioni siano state confrontate in decine di post, non sono riuscito a trovare alcuna spiegazione sul perché una copia debba essere eseguita in caso di post-incremento. Perché non restituisce il vecchio valore e quindi incrementa il valore della variabile di uno (o comunque il modo in cui l'operatore è sovraccarico), piuttosto che creare un nuovo oggetto e restituirlo.

+0

Poiché il post-incremento deve mantenere il valore precedente in un valore temporaneo in modo da restituirlo in seguito. – 101010

+3

'Perché non restituisce il vecchio valore e quindi incrementa il valore della variabile di uno? Come si incrementa il valore se è già stato restituito dalla funzione? –

+0

@RaphaelMiedl grazie raphael, questo era esattamente il punto che mi mancava. Sapevo che era qualcosa di molto banale :) – ralzaul

risposta

7

La differenza è someval++ restituisce ciò che someval è prima dell'incremento e per fare ciò è necessario ricordare cosa è someval con una copia. In quale altro modo si potrebbe restituire il valore originale durante l'aggiornamento se il valore originale non è stato memorizzato da qualche parte?

3

Considerare gli operatori pre-Incremento e post-Incremento come funzioni standard:

// ++i 
int pre_increment(int &i) { 
    i = i + 1; 
    return i; 
} 

// i++ 
int post_increment(int &i) { 
    int original_i = i; 
    i = i + 1; 
    return original_i; 
} 

Questo dovrebbe aiutare a capire il motivo per cui nel secondo caso (i ++), è necessario eseguire una copia del valore prima di fare il Incremento.

2

È difficile per me dire come i compilatori possono ottimizzare gli operatori di pre-incremento e post-incremento in modo che una copia non venga necessariamente eseguita su tipi primitivi.

È possibile mostrare come è necessario eseguire una copia per i tipi definiti dall'utente per gli operatori di post-incremento.

Consente di dare uno sguardo semplicistico a std::vector::iterator.

Diciamo che l'iteratore memorizza un indice, oltre alle altre cose.

struct iterator 
{ 
    size_t index; 

    iterator operator++(int) 
    { 
     iterator copy = *this; 
     this->index++; 
     return copy; 
    } 
}; 

In tal caso, non è possibile restituire *this prima e quindi incrementare l'indice. Creare una copia, incrementare l'indice di this e quindi restituire la copia ci consente di preservare la semantica di tale operazione.

Problemi correlati