Como sobrecarregar o operador ++ de duas maneiras diferentes para postfix a++
e prefix ++a
?
Como sobrecarregar o operador ++ de duas maneiras diferentes para postfix a++
e prefix ++a
?
Respostas:
Deve ser assim:
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)
considera um int
como parâmetro, embora você não o use?
++x
é prefixo e, portanto, chama operator++()
while x++
é pós-fixo e, portanto, chamaoperator++(int)
A diferença está na assinatura que você escolhe para sua (s) sobrecarga (s) operator ++
.
Citado do artigo relevante sobre este assunto no C ++ FAQ (vá lá para mais detalhes):
class Number { public: Number& operator++ (); // prefix ++: no parameter, returns a reference Number operator++ (int); // postfix ++: dummy parameter, returns a value };
PS: Quando descobri sobre isso, tudo que vi inicialmente foi o parâmetro fictício, mas os diferentes tipos de retorno são na verdade mais interessantes; eles podem explicar por que ++x
é considerado mais eficiente do que x++
em geral .
Você tem duas maneiras de sobrecarregar os dois (prefixo / postfix) operadores ++ para um tipo T:
Esta é a maneira mais fácil, usando o idioma OOP "comum".
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 é outra maneira de fazer isso: Contanto que as funções estejam no mesmo namespace que o objeto ao qual estão se referindo, elas serão consideradas quando o compilador procurar uma função para manipular ++t ;
ou 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 ;
}
É importante lembrar que, do ponto de vista C ++ (incluindo um ponto de vista do compilador C ++), essas funções não-membros ainda fazem parte da interface de T (desde que estejam no mesmo namespace).
Existem duas vantagens potenciais da notação de função de não membro:
Declare assim:
class A
{
public:
A& operator++(); //Prefix (++a)
A operator++(int); //Postfix (a++)
};
Implemente corretamente - não mexa com o que todos sabem que eles fazem (incremente e depois use, use e depois incremente).
Sei que é tarde, mas tive o mesmo problema e encontrei uma solução mais simples. Não me interpretem mal, esta é a mesma solução que a principal (postada por Martin York). É um pouco mais simples. Só um pouco. Aqui está:
class Number
{
public:
/*prefix*/
Number& operator++ ()
{
/*Do stuff */
return *this;
}
/*postfix*/
Number& operator++ (int)
{
++(*this); //using the prefix operator from before
return *this;
}
};
A solução acima é um pouco mais simples porque não usa um objeto temporário no método postfix.