Pregunta

Estoy queriendo asegurarse de que entiendo el paso por valor vs pase por referencia correctamente. En particular, estoy mirando a las versiones de prefijo / postfix del operador de incremento ++ para un objeto.

Supongamos que tenemos el siguiente X clase:

class X{
private:
    int i;
public:
 X(){i=0;}
 X& operator ++ (){ ++i; return *this; } //prefix increment

 X operator ++ (int unused){ //postfix increment
  X ret(*this);
  i++;
  return ret;
 }

 operator int(){ return i; } //int cast
};

En primer lugar, tiene implementé los operadores de prefijo / postfijo de incremento correctamente?

En segundo lugar, cómo la memoria de eficiencia es el operador de sufijo, en comparación con el operador de prefijo? Específicamente cuántas X copias de objetos se crean cuando se utiliza cada versión del operador?

Una explicación de lo que sucede exactamente con retorno por referencia vs retorno por valor podría ayudar a entender.


Edit: Por ejemplo, con el siguiente código ...

X a;
X b=a++;

... son a y b alias ahora?

¿Fue útil?

Solución

Esta es una implementación correcta. Es típico que un operador de sufijo será peor en el rendimiento porque hay que crear otra copia antes de hacer el mínimo de la subasta (y es por eso que he recibido en el hábito de usar siempre el prefijo a menos que necesite algo más).

Con el retorno por referencia, se está volviendo una referencia l-valor al objeto actual. El compilador normalmente implementar esta devolviendo la dirección del objeto actual. Esto significa que la devolución del objeto es tan simple como devolver un número.

Sin embargo, la rentabilidad por valor, una copia debe hacerse. Esto significa que hay más información sobre la copia durante el retorno (en lugar de sólo una dirección), así como un constructor de copia a la llamada. Aquí es donde su impacto en el rendimiento entra en acción.

La eficiencia de su apariencia de aplicación a la par con las implementaciones típicas.

EDIT: Con respecto a su adenda, no, no son alias. Ha creado dos objetos separados. Cuando regresa al valor (y al crear un nuevo objeto desde dentro del operador de incremento de sufijo) este nuevo objeto se coloca en una posición de memoria distinta.

Sin embargo, en el siguiente código, a y b son alias:

 int a = 0;
 int& b = ++a;

b es una dirección que las referencias a.

Otros consejos

Es más idiomática para llamar al prefijo de incremento del objeto mismo en el incremento de sufijo:

X operator++(int)
{
    X copy(*this);
    ++*this;         // call the prefix increment
    return copy;
}

La lógica de incrementar un objeto X es así únicamente contenido dentro de la versión de prefijo.

Sus operadores se aplican correctamente.

En el operador de prefijo, no se realizan copias de X.

En el operador de sufijo, se hace una copia para ret, y potencialmente otra copia se realiza, al regresar de la función, pero todos los compiladores eludir esta copia.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top