Muss ich beim Überladen eines Pre-Increment-Operators einen Verweis auf das Objekt zurückgeben?

8

Kann ich verwenden:

%Vor%

Oder es kann sein:

%Vor%

Was ist der Unterschied?

Danke für die Antworten. Ich habe ein anderes Problem.

Viele Leute machen so etwas:

%Vor%

Ist das nicht unlogisch? Bitte geben Sie einige Beispiele, wenn Sie können.

Ich weiß, dass die erste Version pre-increment ist und die zweite post-increment, aber ich frage, warum die erste die Referenz zurückgibt, aber die zweite nicht? Es ist im selben Code (Klasse) und die gleiche Verwendung des Codes.

    
name3r123 16.06.2011, 16:56
quelle

5 Antworten

16

Nein, Sie haben nicht, um den Verweis auf Ihr Objekt zurückzugeben, wenn Sie den Pre-Increment-Operator überladen. In der Tat können Sie alles zurückgeben, was Sie möchten, MyClass , int , void , was auch immer.

Dies ist ein Designproblem - Sie müssen sich fragen, was den Benutzern Ihrer Klasse, die Sie zurückgeben können, am nützlichsten ist.

In der Regel sind Klassenoperatoren am nützlichsten, wenn sie am wenigsten Verwirrung stiften, dh wenn sie am ähnlichsten sind wie Operatoren für Basistypen. In diesem Fall ist der Pre-Increment-Operator auf einem Basistyp:

%Vor%

erhöht die Variable und gibt dann den neuen Wert zurück. Wenn dies die einzige Verwendung ist, die MyClass haben soll, reicht die Rückgabe einer Kopie Ihrer Klasse aus.

Aber der Pre-Increment-Operator eines Basistyps gibt tatsächlich einen Lvalue zurück. Also, das ist legal:

%Vor%

Wenn Sie eine Operation wie diese unterstützen möchten, müssen Sie eine Referenz zurückgeben.

Gibt es einen bestimmten Grund, warum Sie keine Referenz zurückgeben möchten? Ist das kein gut durchdachtes Konzept für Ihre spezielle Klasse? Wenn ja, erwägen Sie, void zurückzugeben. In diesem Fall ist dieser Ausdruck: ++myObject legal, während dieser myOtherObject = ++myObject nicht.

ist     
Robᵩ 16.06.2011, 17:04
quelle
2

Sie können zurückgeben, was Sie wollen. void , Bezug auf Selbst, Kopie von Selbst, etwas anderes. Welches auch immer Sie bevorzugen (oder brauchen).

Wenn Sie vorhaben, den Operator ++ in verketteten Ausdrücken (wie (++obj).something() ) zu verwenden, geben Sie eine Referenz zurück. In dir nicht, dann ist void einfach in Ordnung.

Denken Sie daran, dass die Operatoren am Ende wie normale Methoden sind: Sie können mit ihnen machen, was Sie wollen, vorausgesetzt, Sie respektieren ihren Prototyp.

    
user703016 16.06.2011 17:03
quelle
2

Für Frage zwei:

Präfix gibt wie erwartet eine Referenz zurück. Postfix gibt eine Kopie zurück, um mit dem Verhalten des Postfix-Operators konsistent zu sein.

Zerlege es einfach zu int:

%Vor%

Um dieses Verhalten in einer Klasse implementieren zu können, muss eine Kopie zurückgegeben werden, da der Postfix-Operator den Status des Objekts geändert hat.

Wenn das Programm keine echte Postfix-Operation benötigt, steht es Ihnen natürlich frei, das zu implementieren, was Sie wünschen. Es gibt zwar Standardmethoden zum Schreiben dieser Operatoren (die von den meisten C ++ - Programmierern verstanden werden), aber nichts hindert Sie daran, dies auf unterschiedliche Weise zu implementieren.

Das angegebene Argument über inkorrekte Funktionalität um (obj++)++ ist nicht wirklich wichtig, da dieser Code nicht einmal für POD-Typen (zumindest in Visual Studio 2010) kompiliert wird, da für POD-Typen eine Kopie zurückgegeben wird Temporäre Kopie kann nicht alleine als l-Wert verwendet werden.

Für den Präfixoperator ist jedoch eine Referenz die bevorzugte Rückgabe, da dies das richtige Verhalten für die Verkettung der Operation (++(++obj)) ermöglicht.

    
Chad 16.06.2011 17:41
quelle
2

Es ist nicht obligatorisch, aber wir sollten versuchen, das Überladen des Operators intuitiv zu machen, und es sollte nach dem Operator funktionieren, der überlastet wird.

Wenn wir es tun int i = 10; i ++ = 0 Dann ist die zweite Anweisung nicht erlaubt, sie sagt, dass sie lvalue benötigt, da i ++ den älteren Zustand von i bezeichnet, kein Speicher ... während ++ i = 0 funktioniert einwandfrei .. Um es nur mit der tatsächlichen Operatoren-Präfixversion synchron zu halten, musste reference zurückgegeben werden, so dass sein Rückgabewert in Ausdrücken als lvalue behandelt werden kann.

    
shashank 18.02.2012 18:34
quelle
1

Ja, Sie sollten als Referenz zurückkehren. Keine Notwendigkeit für die Klammer um *this .

BEARBEITEN : Beantworten Sie Ihren Kommentar ... Sie haben nicht , um als Referenz zurückzukehren. Im Allgemeinen folgen wir jedoch einigen Richtlinien, die bewirken, dass sich unsere Klassen "wie erwartet" verhalten, verglichen mit der eingebauten Semantik solcher Operatoren. Vielleicht möchten Sie einen Blick auf Ссылка werfen.

    
Leandro T. C. Melo 16.06.2011 17:00
quelle