【问题标题】:Difference between (++i) and (i++)(++i) 和 (i++) 之间的区别
【发布时间】:2010-06-18 19:09:25
【问题描述】:

在 C++ 中,我知道 (++i) 应该返回对 i 的引用,因为需要连接运算符,但我不知道的是:

为什么(i++) 应该按值返回i

谁能解释一下。

【问题讨论】:

  • 除非你在谈论一种特定的语言,否则 ++i 总是返回值,而不是引用。
  • @all :我很确定这与语言无关。是否有任何语言可以通过引用返回i++?它必须在任何语言的实现中返回一个新值。
  • 根据问题的上下文,我假设他正在谈论重载 C++ 中的 ++ 运算符。澄清这个问题会很有帮助。
  • @Stephen 不,不是。我不理解人们希望在这里立即回答问题,而不试图让提问者详细解释他们的真正问题。为什么急于做出假设?
  • @Neil:因为这样做你有机会赢得一些声誉?

标签: c++ operator-overloading


【解决方案1】:

i++ 返回一个值,因为它返回了i值,而i 增加了1

一个基本的实现是:

int i++() {
  int old = i;
  i = i + 1;
  return old;
}

所以,如果它返回一个引用,那将是错误的值...因为i 的值已经增加了!

【讨论】:

  • 此外,它无法返回对old 的引用,因为您无法返回对临时对象的引用(或指针)。
【解决方案2】:

++i可以写成

prefix_inc (this) {
   increase this by 1
   return this
}

由于返回的是真正的i,我们可以参考它。但是,i++ 看起来像

postfix_inc (this) {
   set old_this = copy of this
   increase this by 1
   return old_this
}

由于old_this只是一个局部变量,在i++完成后对其的引用就没有意义了。所以逻辑上它应该返回一个右值。

【讨论】:

    【解决方案3】:

    foo 成为某个函数。 foo(i++) 使用旧值i 调用foo(i) 并递增i,因此需要构建一个临时副本。 foo(++i) 递增 i,然后使用递增的值调用 foo,因此为了获得更好的性能,我们可以重用相同的变量,无需临时副本。

    【讨论】:

    • foo(i++) 递增 i 并且 then 使用原始值 i 调用 foo。在参数的评估(及其副作用)和函数调用之间有一个序列点。
    【解决方案4】:

    我++ 这将返回 i 在递增之前的值。所以这个想法是,如果你想在一个函数中使用 i,然后在使用它之后增加值,你可以一步完成。 例如,下面是我如何为整数重载该运算符。

    Integer Integer::operator++()
    {
        Integer returnValue = *this;
        this->increment();
        return returnValue;
    }
    

    所以它增加值,然后返回它使用的值。它也不返回引用,因为返回的引用与最初传递的不同,这会破坏级联。

    ++i 这增加了 i 的值,然后返回新值。所以你可以在你想增加 i 然后在你的函数中使用新值的情况下使用它。

    Integer Integer::operator++(Integer i)
    {
        i.increment();
        return i;
    }
    

    所以它返回的值是 i 的递增值。

    【讨论】:

      【解决方案5】:
      int i = 0;
      Console.Writeline(i++); // Output 0, after that, i will be 1
      
      
      int x = 0;
      Console.Writeline(++x); // Output 1
      

      注意:代码在 C# 中

      【讨论】:

        【解决方案6】:

        虽然前缀 ++i 返回增加的值,而后缀 i++ 返回旧值并在之后增加它,但如果您关心 CPU 周期,则运算符选择很重要。前缀增量更快;-)

        【讨论】:

        【解决方案7】:

        5 美分:

        由于i++ 进行复制,非 POD 变量(即迭代器)的速度较慢。您应该尽可能在任何地方使用++i

        我个人总是使用for(...;...;++i) 而不是for(...;...;i++),尽管编译器应该优化它。

        【讨论】:

          【解决方案8】:

          如果您曾经处于重要的场景中,那么您做错了。

          【讨论】:

          • 如果您必须重载该运算符,重要的是您了解它们的工作原理。
          • 我不会对任何不得不使用我的课程的人施加 ++i vs i++。
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2020-02-26
          • 2016-06-29
          • 2021-12-21
          • 1970-01-01
          • 2021-05-03
          • 2013-05-06
          相关资源
          最近更新 更多