为何选择返回?

时间:2014-04-07 12:08:21

标签: c++ reference return return-type

我正在阅读“SAMS在21天内自学C ++”,我遇到了一个我似乎无法理解的例子:

#include<iostream>

using namespace std;

class Counter
{
  public:
    Counter() {itsVal=0;}
    const Counter& operator++ ();
    int GetItsVal() {return itsVal;}
  private:
    int itsVal;
};

const Counter& Counter::operator++()
{
  ++itsVal;
  return *this;
}

int main()
{
  Counter i;
  Counter a = ++i;
  cout << "a: " << a.GetItsVal() << " i: " << i.GetItsVal() << endl;
  ++a;
  cout << "a: " << a.GetItsVal() << " i: " << i.GetItsVal() << endl;
}

为什么会有“&amp;”在++运算符的声明中?我理解这意味着++运算符的返回类型是一个引用,但它似乎不是对i的引用(因为递增a不会增加i)。我注意到如果删除“&amp;”,代码会返回相同的结果,但可能效率不高。

4 个答案:

答案 0 :(得分:5)

在C ++中,当您创建引用时,它是原始对象的代理:

int i = 0;
int& a = i;

++i;
std::cout << i << " " << a << "\n"; // prints '1 1'

++a;
std::cout << i << " " << a << "\n"; // prints '2 2'

现在,在你的情况下:

  • operator++返回对当前对象的引用
  • Counter a = ++i;创建了一个新对象(&之后没有Counter),初始化为对i的引用的副本

如果您希望a引用i,则需要更改其声明:

Counter& a = ++i;
       ^

这将无法编译思维,因为Counter::operator++的返回值为Counter const&:您需要删除const这里operator++非惯用的Counter& Counter::operator++() { ++itsVal; return *this; } 因此:

{{1}}

答案 1 :(得分:2)

许多函数通常会观察其返回值和一般行为的模式,使您可以轻松自然地使用它们。

预增量和预减量运算符在执行链接任务后总是返回对象的引用:

Counter& Counter::operator++()
Counter& Counter::operator--()

虽然后递增和后递减运算符不返回任何值,或者包含旧值的临时值用于容易复制的值类型:

Counter Counter::operator++(int)
Counter Counter::operator--(int)

或者

void Counter::operator++(int)
void Counter::operator--(int)

在你的例子中,似乎有人没有遵循惯例。

答案 2 :(得分:0)

为了让您轻松理解这一点,请考虑赋值运算符重载。


计数器&安培; operator =(const Counter&amp; RHS);

反击a(10),b(20),c,d;

现在,

c = d = a是可能的。当您返回某些内容作为参考时,该重载调用可以用作R值。

答案 3 :(得分:0)

考虑一下:

void someFunction(const Counter& c);
void someFunction(Counter& c);

...

{
  Counter myCount = makeACounter();
  while(myCount.stillCounting()) {
    someFunction(++myCounter);
  }
}

someFunction()需要参考,所以你要做的最后一件事就是复制myCounter,因为它可能效率低下。此外,如果选择someFunction的非const变体(在这种情况下将是这样),传递副本在逻辑上是错误的,因为someFunction可以合法地修改其参数的状态,并且您期望看到函数返回时更改myCounter。

由于上述情况(以及其他情况),operator++应该返回*this的非const引用(你刚刚修改了* this,所以它不能是const吗? )

因此方法签名应该是: Counter& operator++ ();