Jak przeciążyć operator ++ na dwa różne sposoby dla postfiksu a++
i prefiksu ++a
?
Jak przeciążyć operator ++ na dwa różne sposoby dla postfiksu a++
i prefiksu ++a
?
Odpowiedzi:
Powinien wyglądać tak:
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)
przyjmuje się int
parametr jako parametr, mimo że go nie używasz?
++x
jest prefiksem i dlatego wywołuje, operator++()
gdy x++
jest postfiksem, a zatem wywołujeoperator++(int)
Różnica polega na tym, jaki podpis wybierzesz dla swojego przeciążenia operator ++
.
Cytowane z odpowiedniego artykułu na ten temat w C ++ FAQ (przejdź tam, aby uzyskać więcej informacji):
class Number { public: Number& operator++ (); // prefix ++: no parameter, returns a reference Number operator++ (int); // postfix ++: dummy parameter, returns a value };
PS: Kiedy się o tym dowiedziałem, początkowo zobaczyłem tylko parametr zastępczy, ale różne typy zwracanych danych są w rzeczywistości bardziej interesujące; mogą wyjaśnić, dlaczego ++x
jest uważany za bardziej skuteczny niż x++
ogólnie .
Istnieją dwa sposoby na przeciążenie dwóch operatorów (prefiks / postfiks) ++ dla typu T:
To najłatwiejszy sposób, używając „powszechnego” idiomu OOP.
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 ;
}
} ;
Jest to inny sposób: tak długo, jak funkcje znajdują się w tej samej przestrzeni nazw, co obiekt, do którego się odwołują, będą one brane pod uwagę, gdy kompilator będzie szukał funkcji do obsługi ++t ;
lub t++ ;
kodu:
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 ;
}
Należy pamiętać, że z punktu widzenia C ++ (w tym punktu widzenia kompilatora C ++) te funkcje niebędące składnikami są nadal częścią interfejsu T (o ile znajdują się w tej samej przestrzeni nazw).
Istnieją dwie potencjalne zalety notacji funkcji niebędącej składową:
Zadeklaruj tak:
class A
{
public:
A& operator++(); //Prefix (++a)
A operator++(int); //Postfix (a++)
};
Wdrażaj poprawnie - nie mieszaj do tego, co wszyscy wiedzą, że robią (zwiększaj, a potem używaj, używaj, a potem zwiększaj).
Wiem, że jest późno, ale miałem ten sam problem i znalazłem prostsze rozwiązanie. Nie zrozumcie mnie źle, jest to to samo rozwiązanie, co najlepsze (opublikowane przez Martina Yorka). To jest trochę prostsze. Tylko trochę. Oto ona:
class Number
{
public:
/*prefix*/
Number& operator++ ()
{
/*Do stuff */
return *this;
}
/*postfix*/
Number& operator++ (int)
{
++(*this); //using the prefix operator from before
return *this;
}
};
Powyższe rozwiązanie jest nieco prostsze, ponieważ nie wykorzystuje tymczasowego obiektu w metodzie postfix.