C++ 前缀/后缀增量运算符
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3181211/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Prefix/Postfix increment operators
提问by Cam
I'm wanting to make sure I understand pass-by-value vs pass-by-reference properly. In particular, I'm looking at the prefix/postfix versions of the increment ++
operator for an object.
我想确保我正确理解按值传递与按引用传递。特别是,我正在查看++
对象的增量运算符的前缀/后缀版本。
Let's suppose we have the following class X
:
假设我们有以下类X
:
class X{
private:
int i;
public:
X(){i=0;}
X& operator ++ (){ ++i; return *this; } //prefix increment
X operator ++ (int unused){ //postfix increment
X ret(*this);
i++;
return ret;
}
operator int(){ return i; } //int cast
};
First of all, have I implemented the prefix/postfix increment operators properly?
首先,我是否正确实现了前缀/后缀增量运算符?
Second, how memory-efficient is the postfix operator, compared to the prefix operator? Specifically how many X
object copies are created when each version of the operator is used?
其次,与前缀运算符相比,后缀运算符的内存效率如何?具体来说X
,每个版本的操作符在使用时会创建多少个对象副本?
An explanation of exactly what happens with return-by-reference vs return-by-value might help me understand.
对按引用返回与按值返回的确切情况的解释可能有助于我理解。
Edit: For example, with the following code...
编辑:例如,使用以下代码...
X a;
X b=a++;
...are a and b now aliases?
... a 和 b 现在是别名吗?
采纳答案by Shirik
This is a correct implementation. It is typical that a postfix operator will be worse on performance because you have to create another copy before doing the increment (and this is why I've gotten in the habit of always using prefix unless I need something else).
这是一个正确的实现。通常,后缀运算符的性能会更差,因为您必须在执行增量之前创建另一个副本(这就是为什么我养成了总是使用前缀的习惯,除非我需要其他东西)。
With return-by-reference, you're returning an l-value reference to the current object. The compiler would typically implement this by returning the address of the current object. This means that returning the object is as simple as returning a number.
通过引用返回,您将返回对当前对象的左值引用。编译器通常会通过返回当前对象的地址来实现这一点。这意味着返回对象就像返回一个数字一样简单。
However, with return-by-value, a copy must be done. This means there's more information to copy over during the return (instead of just an address) as well as a copy constructor to call. This is where your performance hit comes in.
但是,对于按值返回,必须进行复制。这意味着在返回期间有更多信息要复制(而不仅仅是地址)以及要调用的复制构造函数。这就是您的表现受到影响的地方。
The efficiency of your implementation looks on-par with typical implementations.
您的实现效率看起来与典型实现不相上下。
EDIT: With regards to your addendum, no, they are not aliases. You have created two separate objects. When you return by value (and when you created a new object from within the postfix increment operator) this new object is placed in a distinct memory location.
编辑:关于您的附录,不,它们不是别名。您已经创建了两个单独的对象。当您按值返回时(以及当您从后缀递增运算符中创建一个新对象时),这个新对象被放置在一个不同的内存位置。
However, in the following code, a and b arealiases:
但是,在以下代码中,a 和 b是别名:
int a = 0;
int& b = ++a;
b is an address which references a.
b 是引用 a 的地址。
回答by fredoverflow
It is more idiomatic to call the prefix increment of the object itselfin the postfix increment:
在后缀增量中调用对象本身的前缀增量更为惯用:
X operator++(int)
{
X copy(*this);
++*this; // call the prefix increment
return copy;
}
The logic of incrementing an X
object is thus solely contained inside the prefix version.
因此,递增X
对象的逻辑仅包含在前缀版本中。
回答by Peter Alexander
Your operators are implemented correctly.
您的运算符已正确实施。
In the prefix operator, no copies of X are made.
在前缀运算符中,不制作 X 的副本。
In the postfix operator, one copy is made for ret, and potentiallyanother copy is made when returning from the function, but all compilers will elide this copy.
在后缀运算符中,为 ret 创建一个副本,并且可能在从函数返回时创建另一个副本,但所有编译器都将忽略此副本。