Wie kann man den Operator ++ auf zwei verschiedene Arten für Postfix a++
und Präfix überladen ++a
?
Wie kann man den Operator ++ auf zwei verschiedene Arten für Postfix a++
und Präfix überladen ++a
?
Antworten:
Sollte so aussehen:
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)
ein int
als Parameter verwendet, obwohl Sie ihn nicht verwenden?
++x
ist Präfix und ruft somit auf, operator++()
während x++
Postfix ist und somit anruftoperator++(int)
Der Unterschied liegt darin, welche Signatur Sie für Ihre Überladung (en) von wählen operator ++
.
Zitiert aus dem entsprechenden Artikel zu diesem Thema in den C ++ - FAQ (weitere Informationen finden Sie dort):
class Number { public: Number& operator++ (); // prefix ++: no parameter, returns a reference Number operator++ (int); // postfix ++: dummy parameter, returns a value };
PS: Als ich davon erfuhr, sah ich anfangs nur den Dummy-Parameter, aber die verschiedenen Rückgabetypen sind tatsächlich interessanter. Sie könnten erklären, warum dies ++x
als effizienter als x++
allgemein angesehen wird .
Sie haben zwei Möglichkeiten, die beiden (Präfix / Postfix) ++ - Operatoren für einen Typ T zu überladen:
Dies ist der einfachste Weg, wenn Sie die "allgemeine" OOP-Sprache verwenden.
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 ;
}
} ;
Dies ist eine andere Möglichkeit, dies zu tun: Solange sich die Funktionen im selben Namespace befinden wie das Objekt, auf das sie sich beziehen, werden sie berücksichtigt, wenn der Compiler nach einer Funktion sucht, die verarbeitet ++t ;
oder t++ ;
codiert werden soll:
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 ist wichtig, sich daran zu erinnern, dass diese Nicht-Mitgliedsfunktionen aus Sicht von C ++ (einschließlich eines C ++ - Compilers) immer noch Teil der Schnittstelle von T sind (solange sie sich im selben Namespace befinden).
Es gibt zwei mögliche Vorteile der Nicht-Mitgliedsfunktionsnotation:
Erklären Sie wie folgt:
class A
{
public:
A& operator++(); //Prefix (++a)
A operator++(int); //Postfix (a++)
};
Richtig implementieren - nicht mit dem herumspielen, von dem jeder weiß, dass er es tut (inkrementieren, dann verwenden, verwenden, dann erhöhen).
Ich weiß, dass es spät ist, aber ich hatte das gleiche Problem und fand eine einfachere Lösung. Versteh mich nicht falsch, dies ist die gleiche Lösung wie die Top-Lösung (gepostet von Martin York). Es ist nur ein bisschen einfacher. Nur ein wenig. Hier ist es:
class Number
{
public:
/*prefix*/
Number& operator++ ()
{
/*Do stuff */
return *this;
}
/*postfix*/
Number& operator++ (int)
{
++(*this); //using the prefix operator from before
return *this;
}
};
Die obige Lösung ist etwas einfacher, da in der Postfix-Methode kein temporäres Objekt verwendet wird.