C++多个运算符重载在单行中的使用引发的意外输出

huangapple go评论64阅读模式
英文:

C++ unexpected output elicited by the multiple operator overloading usage in a single line

问题

I understand that you want the code portion to be translated. Here's the translated code:

#include <iostream>
using namespace std;

class Power {
    int kick;
    int punch;
public:
    Power(int kick = 0, int punch = 0) {
        this->kick = kick;
        this->punch = punch;
    }
    void show();
    Power operator<<(int n); 
};

void Power::show() {
    cout << "kick=" << kick << ',' << "punch=" << punch << endl;
}

Power Power::operator<<(int n) {
    kick += n;
    punch += n;
    return *this;
}

int main() {
    Power a(1, 2);
    a << 3 << 5 << 6; 
    a.show();
}

I hope this helps with your code translation. If you have any further questions or need assistance with the code, please feel free to ask.

英文:

I'm a student who is learning C++ (especially the operator overloading part). During my study, I found the following code that uses operator overloading doesn't make an expected output. At first, the code with which I have trouble is the...

#include &lt;iostream&gt;
using namespace std;

class Power {
	int kick;
	int punch;
public:
	Power(int kick = 0, int punch = 0) {
		this-&gt;kick = kick; this-&gt;punch = punch;
	}
	void show();
	Power operator &lt;&lt; (int n); 
};

void Power::show() {
	cout &lt;&lt; &quot;kick=&quot; &lt;&lt; kick &lt;&lt; &#39;,&#39; &lt;&lt; &quot;punch=&quot; &lt;&lt; punch &lt;&lt; endl;
}


Power Power::operator &lt;&lt;(int n) {
	kick += n;
	punch += n;
	return *this; 
}

int main() {
	Power a(1, 2);
	a &lt;&lt; 3 &lt;&lt; 5 &lt;&lt; 6; 
	a.show();
}

The overloaded operator &lt;&lt; was designed for adding the integer to all member variables of the instance. I installed &lt;&lt; operators three times in a single line such as a + 3 + 5 + 6. I expected the output will be kick=15,punch=16, but the console shows kick=4,punch=5 as a result of that code. It seems that only the first &lt;&lt; operation works and the behind code doesn't work at all as I expected like parallelly connected math operators.

I know this unexpected behavior of the suggested code will be simply fixed by adding &amp;(reference) to the operator overloading like Power&amp; operator &lt;&lt; (int n); , but I can't grasp why these make totally different outputs. When I utilized the debugging feature in Visual Studio, the calculated outputs since the second overloaded operation aren't applied to the target a, but I couldn't find more answers beyond just the behavior.

答案1

得分: 3

如你所发现,你需要使用 &amp; 来返回 this 的引用。

发生了什么呢?

a &lt;&lt; 3

创建了一个新的 Power 对象,因为你返回的是 Power 而不是 Power&amp;

我们称这个新对象为 b。接下来发生的是:

b &lt;&lt; 5

同样,这返回了一个类型为 Power 的新对象。我们将其称为 c。最后发生了这个:

c &lt;&lt; 6

表达式返回了具有正确结果的 c,但你没有捕获该值。你可以这样做:

c = a &lt;&lt; 3 &lt;&lt; 5 &lt;&lt; 6;

然后验证 c 是否符合你的预期:

c.show();

你还可以这样捕获 b(由于你在学习,不要编写这样的表达式,它非常晦涩):

c = (b = a &lt;&lt; 3) &lt;&lt; 5 &lt;&lt; 6;

在运算符中忘记 &amp; 是一个常见的错误。或者说,有些运算符返回一个副本(operator + (...)),而其他运算符预期返回一个引用(operator += (...)),经常我们复制/粘贴然后忘记调整返回值,它在大多数情况下似乎可以工作,但当你串联它时,它开始以非常奇怪的方式失败...

英文:

As you discovered, you need that &amp; to return a reference of this.

What really happens?

a &lt;&lt; 3

creates a new Power object since you return Power instead of Power&amp;.

Let's call that new object b. Then what happens next is:

b &lt;&lt; 5

Again, that returns a new object of type Power. Let's call this one c. Finally this happens:

c &lt;&lt; 6

The expression returns c with the correct result, but you do not capture that value. You could do so with:

c = a &lt;&lt; 3 &lt;&lt; 5 &lt;&lt; 6;

Then verify that c is what you expect:

c.show();

You could also capture b like so (since you're learning, just don't write such expressions, it's very cryptic):

c = (b = a &lt;&lt; 3) &lt;&lt; 5 &lt;&lt; 6;

Forgetting the &amp; in an operator is a common mistake. Or rather, some operators return a copy (operator + (...)) and others are expected to return a reference (operator += (...)) and it's often that we copy/paste and forget to tweak the return value and it looks like it works in most cases and when you daisy chain it starts failing in really strange ways...

答案2

得分: 0

Power Power::operator<<(int n) {
这将返回一个Power对象的副本。在进一步的<<操作中,这个新对象将被修改。你的意思是在执行更多的<<操作时修改同一个对象。

你应该这样做:

Power& Power::operator<<(int n) {
然后,相同的对象将通过引用返回。

英文:
Power Power::operator &lt;&lt;(int n) {

This returns a copy of your Power object. This new object will be modified in further &lt;&lt; operations. What you mean to do is modify the same object three times as you perform more &lt;&lt; operations.

You should do:

Power&amp; Power::operator &lt;&lt;(int n) {
...

then, the same object would be returned, by reference.

huangapple
  • 本文由 发表于 2023年5月15日 11:16:40
  • 转载请务必保留本文链接:https://go.coder-hub.com/76250679.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定