前缀/后缀增量运算符
-
02-10-2019 - |
题
我想确保正确理解逐个传递与逐次通过的通行。特别是,我正在查看增量的前缀/后缀版本 ++
对象的操作员。
让我们假设我们有以下课程 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
};
首先,我是否正确地实现了前缀/后缀增量运算符?
其次,与前缀操作员相比,后缀操作员的内存效率如何?特别是多少 X
当使用操作员的每个版本时,创建对象副本?
关于逐回报与逐个价值返回的确切说明可能会帮助我理解。
编辑:例如,使用以下代码...
X a;
X b=a++;
...现在是A和B现在别名吗?
解决方案
这是正确的实现。典型的是,后缀操作员的性能会更糟,因为您必须在进行增量之前创建另一个副本(这就是为什么我习惯始终使用前缀的原因,除非我需要其他东西)。
通过返回参考,您将返回对当前对象的L值引用。编译器通常会通过返回当前对象的地址来实现此目标。这意味着返回对象就像返回数字一样简单。
但是,在逐个价值的情况下,必须完成副本。这意味着在返回期间(而不是仅仅是地址)以及复制构造函数需要复制更多信息。这是您的表现打击的地方。
实施的效率与典型的实现相比具有出色的作用。
编辑:关于您的附录,不,它们不是别名。您创建了两个单独的对象。当您按值返回时(以及从Postfix增量运算符中创建一个新对象时)将该新对象放在不同的内存位置中。
但是,在以下代码中,A和B 是 别名:
int a = 0;
int& b = ++a;
b是引用a的地址。
其他提示
调用前缀增量更为惯用 对象本身 在后缀增量中:
X operator++(int)
{
X copy(*this);
++*this; // call the prefix increment
return copy;
}
增量的逻辑 X
因此,对象仅包含在前缀版本中。
您的操作员已正确实施。
在前缀操作员中,没有制作X的副本。
在后缀操作员中,为RET制作了一份副本,并且 可能 从函数返回时,将制作另一副副本,但所有编译器都将出现此副本。
不隶属于 StackOverflow