2010-06-18 26 views
10

En C++ entiendo que (++i) debe devolver una referencia a i debido a la necesidad de la concatenación de los operadores, pero lo que no puedo entender es:diferencia entre (++ i) y (i ++)

Por qué (i++) debe devolver i por valor?

¿Puede alguien aclarar por favor?

+1

A menos que esté hablando de un idioma específico, ++ siempre devuelvo el valor, no una referencia. – HoLyVieR

+0

@all: estoy bastante seguro de que esto está bien como agnóstico del lenguaje. ¿Hay algún lenguaje que pueda devolver 'i ++' por referencia? Debo devolver un nuevo valor en la implementación de cualquier idioma. – Stephen

+0

Basado en el contexto de la pregunta, supongo que está hablando de sobrecargar el operador ++ en C++. Una aclaración de la pregunta sería útil. – 5ound

Respuesta

18

++i se puede escribir como

prefix_inc (this) { 
    increase this by 1 
    return this 
} 

Desde el verdadero i se devuelve, podemos tomar referencia de la misma. Sin embargo, parece i++

postfix_inc (this) { 
    set old_this = copy of this 
    increase this by 1 
    return old_this 
} 

como old_this es sólo una variable local, la referencia de que es inútil después de i++ se ha completado. Entonces lógicamente debería devolver un valor r.

27

i++ devuelve un valor porque es devuelve el valor antiguo de i, mientras i se incrementa en 1.

una implementación básica de esto sería:

int i++() { 
    int old = i; 
    i = i + 1; 
    return old; 
} 

Por lo tanto, si se devuelve una referencia, sería el valor incorrecto ... desde i 's valor se ha incrementado!

+2

Además, no puede devolver una referencia a 'old', porque no puede devolver una referencia (o un puntero) a un temporal. –

4

Deje foo ser alguna función. foo(i++) llama al foo(i) con el valor anterior de i e incrementa i, de ahí la necesidad de crear una copia temporal. foo(++i) incrementa i y luego llama al foo con el valor incrementado, por lo que para un mejor rendimiento podemos reutilizar la misma variable, sin necesidad de tener una copia temporal.

+4

'foo (i ++)' incrementa 'i' y _then_ llama a' foo' con el valor original de 'i'. Hay un punto de secuencia entre la evaluación del parámetro (con su efecto secundario) y la llamada a la función. –

-4

Si alguna vez te encuentras en un escenario en el que importa, lo estás haciendo mal.

+5

Si tiene que sobrecargar ese operador, es importante que comprenda cómo funcionan. – chustar

+0

No infligiría ++ i vs i ++ a nadie que tuviera que usar mi clase. – Puppy

1
int i = 0; 
Console.Writeline(i++); // Output 0, after that, i will be 1 


int x = 0; 
Console.Writeline(++x); // Output 1 

Nota: es el código de C#

2

i ++ Esto devuelve el valor de la i antes de que se incrementa. Entonces, la idea es que si desea usar i en una función y luego incrementar el valor después de usarlo, puede hacerlo en un solo paso. Como ejemplo, aquí es cómo sobrecargaría ese operador para enteros.

Integer Integer::operator++() 
{ 
    Integer returnValue = *this; 
    this->increment(); 
    return returnValue; 
} 

Por lo tanto, incrementa el valor y luego devuelve lo que utiliza ser. Tampoco devuelve una referencia, porque devolver una referencia sería diferente de lo que se aprobó originalmente, lo que rompería en cascada.

++ i Esto incrementa el valor de i, y luego devuelve el nuevo valor. De modo que podría usar esto en una situación en la que desee incrementar i y luego usar el nuevo valor en su función.

Integer Integer::operator++(Integer i) 
{ 
    i.increment(); 
    return i; 
} 

Así que el valor que devuelve es el valor incrementado de i.

0

Mientras que el prefijo ++i devuelve el valor incrementado y el sufijo i++ devuelve el valor anterior y lo incrementa después, la selección del operador es significativa si se preocupan por los ciclos de la CPU. incremento de prefijo es más rápido ;-)

+0

¿Por qué el incremento del prefijo es más rápido? –

+0

Los compiladores simplistas pueden crear una variable temporal para almacenar el valor intermedio. No cuesta nada para tipos estándar como 'int' pero por ejemplo. objetos puede ser costoso. Importa si su aplicación está vinculada a la CPU. Ver http://www.parashift.com/c++-faq-lite/operator-overloading.html#faq-13.15 – puudeli

0

5 centavos:

Como consecuencia de i++ hacer una copia, es más lento para las variables no-POD (es decir iteradores). Debe usar ++i en cualquier lugar cuando sea posible.

Personalmente siempre uso for(...;...;++i) en lugar de for(...;...;i++), aunque compiller debería optimizar eso.

Cuestiones relacionadas