¿Cómo sobrecargar el operador ++ de dos formas diferentes para sufijo a++
y prefijo ++a
?
¿Cómo sobrecargar el operador ++ de dos formas diferentes para sufijo a++
y prefijo ++a
?
Respuestas:
Debería verse así:
class Number
{
public:
Number& operator++ () // prefix ++
{
// Do work on this. (increment your object here)
return *this;
}
// You want to make the ++ operator work like the standard operators
// The simple way to do this is to implement postfix in terms of prefix.
//
Number operator++ (int) // postfix ++
{
Number result(*this); // make a copy for result
++(*this); // Now use the prefix version to do the work
return result; // return the copy (the old) value.
}
};
Number operator++ (int)
toma an int
como parámetro aunque no lo use?
++x
is prefix y por lo tanto llama operator++()
while x++
is postfix y por tanto llamaoperator++(int)
La diferencia radica en qué firma elige para su (s) sobrecarga (s) de operator ++
.
Citado del artículo relevante sobre este tema en las preguntas frecuentes de C ++ (vaya allí para obtener más detalles):
class Number { public: Number& operator++ (); // prefix ++: no parameter, returns a reference Number operator++ (int); // postfix ++: dummy parameter, returns a value };
PD: Cuando me enteré de esto, todo lo que vi inicialmente fue el parámetro ficticio, pero los diferentes tipos de retorno son en realidad más interesantes; podrían explicar por qué ++x
se considera más eficiente que x++
en general .
Tiene dos formas de sobrecargar los dos operadores (prefijo / sufijo) ++ para un tipo T:
Esta es la forma más sencilla, utilizando el modismo de programación orientada a objetos "común".
class T
{
public :
T & operator++() // ++A
{
// Do increment of "this" value
return *this ;
}
T operator++(int) // A++
{
T temp = *this ;
// Do increment of "this" value
return temp ;
}
} ;
Esta es otra forma de hacer esto: siempre que las funciones estén en el mismo espacio de nombres que el objeto al que se refieren también, se considerarán cuando el compilador busque una función para manejar ++t ;
o t++ ;
codificar:
class T
{
// etc.
} ;
T & operator++(T & p_oRight) // ++A
{
// Do increment of p_oRight value
return p_oRight ;
}
T operator++(T & p_oRight, int) // A++
{
T oCopy ;
// Copy p_oRight into oCopy
// Do increment of p_oRight value
return oCopy ;
}
Es importante recordar que, desde el punto de vista de C ++ (incluido el punto de vista del compilador de C ++), esas funciones que no son miembros siguen siendo parte de la interfaz de T (siempre que estén en el mismo espacio de nombres).
Hay dos ventajas potenciales de la notación de función no miembro:
Declare así:
class A
{
public:
A& operator++(); //Prefix (++a)
A operator++(int); //Postfix (a++)
};
Implemente correctamente: no se meta con lo que todos saben que hacen (incremente y luego use, use y luego incremente).
Sé que es tarde, pero tuve el mismo problema y encontré una solución más simple. No me malinterpretes, esta es la misma solución que la principal (publicada por Martin York). Es un poco más simple. Solo un poco. Aquí está:
class Number
{
public:
/*prefix*/
Number& operator++ ()
{
/*Do stuff */
return *this;
}
/*postfix*/
Number& operator++ (int)
{
++(*this); //using the prefix operator from before
return *this;
}
};
La solución anterior es un poco más simple porque no usa un objeto temporal en el método postfix.