C++在前缀重载中返回引用变量
当我发现的所有代码都显示在重载前缀运算符时返回引用变量时,我感到很困惑。我浏览了 parashift.com 常见问题解答(http://www.parashift.com/c++-faq-lite/operator-overloading.html#faq-13.14),但不清楚,尽管它说会很清楚当你读到它的时候。我将他们的示例改编成一个无意义的、毫无意义的小程序来测试。
#include<iostream>
using namespace std;
class Number {
public:
Number& operator++ (); // prefix ++
Number operator++ (int); // postfix ++
int value() { return value_; }
void setValue(int value) { value_ = value; }
private:
int value_;
};
Number& Number::operator++ () {
++value_;
return *this;
}
Number Number::operator++ (int unused) {
Number temp;
temp.setValue(value_);
++value_;
return temp;
}
int main()
{
Number someNum;
someNum.setValue(20);
cout << "someNum : " << someNum.value() << "\n";
someNum++;
++someNum;
cout << "someNum : " << someNum.value() << "\n";
return 0;
}
问题是,如果我只是将其声明为 Number 对象,就像这样:
#include<iostream>
using namespace std;
class Number {
public:
Number operator++ (); // prefix ++
Number operator++ (int); // postfix ++
int value() { return value_; }
void setValue(int value) { value_ = value; }
private:
int value_;
};
Number Number::operator++ () {
++value_;
return *this;
}
Number Number::operator++ (int unused) {
Number temp;
temp.setValue(value_);
++value_;
return temp;
}
int main()
{
Number someNum;
someNum.setValue(20);
cout << "someNum : " << someNum.value() << "\n";
someNum++;
++someNum;
cout << "someNum : " << someNum.value() << "\n";
return 0;
}
我假设我只是需要更好地理解引用变量。谁能简单地解释一下为什么前缀运算符应该被编码为返回引用变量?
I am confused when all the code I find shows returning a reference variable when overloading the prefix operator. I went through the parashift.com FAQ (http://www.parashift.com/c++-faq-lite/operator-overloading.html#faq-13.14) and it isn't clear, even though it says it WILL be clear when you read it. I adapted their example into a nonsensical, pointless little program to test.
#include<iostream>
using namespace std;
class Number {
public:
Number& operator++ (); // prefix ++
Number operator++ (int); // postfix ++
int value() { return value_; }
void setValue(int value) { value_ = value; }
private:
int value_;
};
Number& Number::operator++ () {
++value_;
return *this;
}
Number Number::operator++ (int unused) {
Number temp;
temp.setValue(value_);
++value_;
return temp;
}
int main()
{
Number someNum;
someNum.setValue(20);
cout << "someNum : " << someNum.value() << "\n";
someNum++;
++someNum;
cout << "someNum : " << someNum.value() << "\n";
return 0;
}
The problem is, it works if I just declare it as a Number object as well like so:
#include<iostream>
using namespace std;
class Number {
public:
Number operator++ (); // prefix ++
Number operator++ (int); // postfix ++
int value() { return value_; }
void setValue(int value) { value_ = value; }
private:
int value_;
};
Number Number::operator++ () {
++value_;
return *this;
}
Number Number::operator++ (int unused) {
Number temp;
temp.setValue(value_);
++value_;
return temp;
}
int main()
{
Number someNum;
someNum.setValue(20);
cout << "someNum : " << someNum.value() << "\n";
someNum++;
++someNum;
cout << "someNum : " << someNum.value() << "\n";
return 0;
}
I assume I simply need a better understanding of reference variables. Can anyone explain simply why the prefix operator SHOULD be coded as returning a reference variable?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
之间的区别
:和
在于,当您使用第一个代码时,以下表达式:
将
someNum
递增三次。请参阅此处的输出: http://ideone.com/y9UlY但是,当您使用第二个时,此
值会增加
someNum
仅一次!!请参阅此处的输出: http://ideone.com/eOLdj这是因为当您从
operator++()
,第二个和第三个++
调用同一个名为someNum
的对象,因此,它始终递增同一个对象。但是,当您按值返回时,第二个和第三个++
会调用从operator++()
返回的临时对象。因此,第二次和第三次调用不会增加someNum
,而是增加在表达式末尾被销毁的临时对象。现在,如果临时对象被销毁,为什么还要创建呢?毕竟,它的预自增运算符意味着临时对象和原始对象将具有相同的值。因此,好的设计决策是,在定义预自增运算符时按引用返回,以避免创建临时值,并提高性能。
The difference between :
and
is that, when you use the first code, the following expression:
increments
someNum
THRICE. See the output here: http://ideone.com/y9UlYHowever, when you use the second one, this
increments
someNum
just ONCE!! See the output here: http://ideone.com/eOLdjIt is because when you return the reference from
operator++()
, the second and third++
invokes on the same object calledsomeNum
and therefore, it increments the same object, all the times. But when you return by value, the second and third++
invokes on the temporary object which you returned fromoperator++()
. Hence, the second and third call doesn't incrementsomeNum
, instead it increments the temporary objects which get destroyed at the end of the expression.Now if the temporary objects get destroyed, why create then in the first place? After all, its pre-increment operator, which means the temporary and the original object will have the same value. So the good design decision is, return by reference when defining pre-increment operator, to avoid creating temporary, and improve performance.
首先,存在效率问题。您正在创建该类的新实例,以便无缘无故地返回它。
其次,还有语义问题。您的代码调用空构造函数或复制构造函数来创建临时对象,然后析构临时对象。如果它具有不恰当的语义,那么该代码实际上并不起作用,只是看起来起作用了。
第三,代码返回错误的内容。考虑:
++foo.do_something();
。通过您的代码,我们在临时对象上调用“do_something”。我们想要在预递增的foo
上调用do_something()
。First, there's an efficiency issue. You are creating a new instance of the class in order to return it for no reason.
Second, there's the semantic issue. Your code invokes the empty constructor or the copy constructor to make the temporary and then destructs the temporary. If that has semantic meaning that's inappropriate, then the code doesn't really work, it just appears to.
Third, the code returns the wrong thing. Consider:
++foo.do_something();
. With your code, we call 'do_something' on the temporary object. We wanted to calldo_something()
on the pre-incrementedfoo
.