Überladen des Inkrement-Operator
-
Ich habe mich jetzt mal mit dem Überladen von Operatoren auseindergesetzt, komme aber nicht wirklich zurecht. Hier mal die Klasse mit dem Versuch:
class WEIRD { public: int i; template <class T> T& WEIRD::operator++ () { return --T; } };Der Operator soll eben irgendeinen Typ dekrementieren. Wenn ich das aber mit i probier, wird i inkrementiert und nicht dekrementiert.
-
In deinem Fall weiss der Compiler nicht, dass er auf int arbeiten soll, die Operator wird lediglich auf WEIRD ausgeführt.
-
Du kannst keinen Operator für fremde Objekte auf die Weise überladen - und einen Typ zu dekrementieren macht auch herzlich wenig Sinn (erstaunlich, daß der Compiler das '--T;' überhaupt schluckt).
PS: Was hast du eigentlich vor?
-
Du kannst keinen Typen Inkrementieren oder Dekrementieren.
T ist ein Typ und keine Variable.
Im Übrigen solltest du auch mal die Forensuche benutzen, so was ist hier schon lange vor dir beantwortet worden
-
Warum du ein Template benutzt, weiß ich jetzt nicht...
Es könnte so aussehen (ungetestet):
class Foo { private: int value; public: Foo(); Foo(int value); Foo& operator++(); }; // [...] Foo& Foo::operator++() { value++; return *this; }Das return *this (zur Erinnerung: this ist ein Zeiger und ein Referenz wird zurückgegeben) ist notwendig, damit ausdrücke wie
Foo foo(12); Foo bar = foo++;möglich sind (die Zweite Zeile ruft den Kopierkonstruktor von Foo mit der (konstanten) Referenz auf auf die Foo-Instanz foo auf).
Grüße...
Heiko
-
bwbg schrieb:
Foo foo(12); Foo bar = foo++;möglich sind (die Zweite Zeile ruft den Kopierkonstruktor von Foo mit der (konstanten) Referenz auf auf die Foo-Instanz foo auf).
Für die zweite Zeile benötigst du aber einen anderen Operator - operator++() ist das Präfix-Inkrement ++foo, operator++(int) ist das Postfix-Inkrement foo++ (der int-Parameter dient nur zur Unterscheidung und wird mit 0 gefüllt).
-
So also erstmal ganz allgemein: Ich möchte einfach nur, dass ++ umgedreht wird.
Und das Template wollte ich benutzen, damit ich nicht für jeden Zahl-Typ (int, float, double, etc.) den Operator überladen muss.EDIT: ich habe mir auch schon etliche tutorials dazu angeguckt, aber ich glaube ich bin zu blöd dafür...
-
BitWax schrieb:
Und das Template wollte ich benutzen, damit ich nicht für jeden Zahl-Typ (int, float, double, etc.) den Operator überladen muss.
Nochmal: Du kannst den operator++ für Zahlen-Typen garnicht überladen.
-
BitWax schrieb:
Und das Template wollte ich benutzen, damit ich nicht für jeden Zahl-Typ (int, float, double, etc.) den Operator überladen muss.
Du kannst Operatoren nicht für Build-in Typen überladen - mindestens ein Operand muß von einem selbstdefinierter Typ sein (beim Inkrement gibt es nur einen Operanden).
-
Hmmm. Also so wie ich da verstanden hatte (aus den Tutorials her) steht als erstes der Linke Bezeichner. Danach kommt der Operator und in den Klammern dann der rechte Bezeichner. Also:
LINKS klasse::operator= (RECHTS) { LINKS = LINKS - RECHTS; return LINKS; }Das Beispiel soll nichts anderes machen, als das wenn man zum Beispiel schreibt:
int a = 5, b = 3; a = b;Dass a dann eben gleich 2 ist.
EDIT: die geschichte natürlich noch auf eine Klasse angewendet.
-
so natürlich ist das nicht, denn unter c++ sind die datentypen keine eigenständigen klassen
-
ich verbesser das mal, eben auf eine klasse angewendet:
LINKS& klasse::operator= (RECHTS) { LINKS = LINKS - RECHTS; return LINKS; } . . . klasse kl; kl.a = 5; kl.b = 3; kl.a = kl.b;
-
Vielleicht solltest du dir nochmal den Unterschied zwischen Typ und Variable ansehen. (oder reden wir hier von einer typlosen Scriptsprache mit C++ ähnlicherSyntax?)
//als Methode // linker Operand ist *this (Typ LINKS) // rechter Operand ist r (Typ RECHTS) // Rückgabe hat Typ ERGEBNIS ERGEBNIS LINKS::operator*(RECHTS r) { ERGEBNIS e = mult(*this,r); return e; } //bzw: //als globale Funktion ERGEBNIS operator*(LINKS l,RECHTS r) { ERGEBNIS e = mult(l,r); return e; }Und der operator= einer Klasse bezieht sich nicht auf Zuweisungen zwischen Membervariablen, sondern auf Zuweisungen der Klasse gesamt:
klasse k1,k2; k1=k2;//hier greift op=
-
Achso! ich dachte das hier
blabla::operator...
muss eine klasse sein! zumindest blabla.
-
BitWax schrieb:
Achso! ich dachte das hier
blabla::operator...
muss eine klasse sein! zumindest blabla.
Strenggenommen (ohne Zusammenhang) muss blabla hier eine Klasse oder ein Namespace sein.
-
Ich habe das jetzt mal versucht, einen Operator global zu überladen:
int operator+ (int l, int r) { return l - r; }und das sagt er mir beim compilieren:
Error E2082 main.cpp 5: 'operator +(int,int)' must be a member function or have a parameter of class typeund so probiere ich es
int main () { int a = 5; int b = 4; cout << a + b << endl; return 0; }Bitte nicht schlagen, wenns komplett falsch ist, aber das ist echt absolutes Neuland.
-
Auch für globale Operatorfunktionen gilt, was LordJaxom und ich vorhin gesagt haben:
CStoll schrieb:
BitWax schrieb:
Und das Template wollte ich benutzen, damit ich nicht für jeden Zahl-Typ (int, float, double, etc.) den Operator überladen muss.
Du kannst Operatoren nicht für Build-in Typen überladen - mindestens ein Operand muß von einem selbstdefinierter Typ sein (beim Inkrement gibt es nur einen Operanden).
-
auf deutsch: selbst wenn ich den global überladen will, muss immer eine eigene klasse/struktur damit verbunden werden?
-
Ja, oder anders gesagt: Der Compiler verbietet Dir aus gutem Grund, die Bedeutung von (z.B.) 1+1 zu ändern.
-
Schade! Eigentlich wollte ich ne DLL basteln, dort alle Operatoren verändern und die DLL dann rausgeben[/ironie]
Naja, versteh schon warum, aber das nervt mich gerade ein bisschen...