我想确保正确理解逐个传递与逐次通过的通行。特别是,我正在查看增量的前缀/后缀版本 ++ 对象的操作员。

让我们假设我们有以下课程 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制作了一份副本,并且 可能 从函数返回时,将制作另一副副本,但所有编译器都将出现此副本。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top