我在这里做错了什么(在C ++中引用)?

时间:2010-06-12 22:11:45

标签: c++ reference

我一直在玩引用(我在这方面仍有问题)。

1-我想知道这是否是可接受的代码:

int & foo(int &y)
{
    return y;  // is this wrong?
}

int main()
{
    int x = 0;    
    cout << foo(x) << endl;

    foo(x) = 9;   // is this wrong?
    cout << x << endl;

    return 0;
}

2-这也来自考试样本:

Week & Week::highestSalesWeek(Week aYear[52])
{
  Week max = aYear[0];
  for(int i = 1; i < 52; i++)
  {
    if (aYear[i].getSales() > max.getSales())
      max = aYear[i];
  }
  return max;
}

它询问此代码中的错误,以及如何修复它。

我的猜测是它返回一个本地引用。 修复是:

Week & max = aYear[0];

这是正确/足够吗?

3 个答案:

答案 0 :(得分:5)

第一个是正确的。

对于第二个,有无数个解决方案:),但这将是我的:

Week Week::highestSalesWeek(Week aYear[52]) // return a copy of the week
{ 
  Week max = aYear[0]; 
  for(int i = 1; i < 52; i++) 
  { 
    if (aYear[i].getSales() > max.getSales()) max = aYear[i]; 
  } 
  return max; 
} 

如果max是引用,则每次执行时都会修改aYear的第一个元素:

max = aYear[i]

此外,您可以使用指针返回对周的引用:

Week & Week::highestSalesWeek(Week aYear[52])
{ 
  Week* max = &aYear[0]; 
  for(int i = 1; i < 52; i++) 
  { 
    if (aYear[i].getSales() > max->getSales()) max = &aYear[i]; 
  } 
  return *max; 
} 

答案 1 :(得分:2)

关于引用的重要一点是始终确保引用不是超出范围的对象。

这是你的第二个例子的问题:

Week & Week::highestSalesWeek(Week aYear[52])
{
  Week max = aYear[0];
  return max;
}

max是该方法的本地自动变量。当该方法超出范围时,max超出范围,现在您的代码引用了随机内存。

由于您的代码要继续重新分配max,因此您无法使用引用(因为在初始赋值之后,您只能修改引用的内容,而不是引用本身)。您需要跟踪要返回引用的aYear的实际部分。两个建议。

// By pointer
Week & Week::highestSalesWeek(Week aYear[52])
{
  Week *max = &aYear[0];
  ...;
  return *max;
}

// By index
Week & Week::highestSalesWeek(Week aYear[52])
{
  size_t max_idx = 0;;
  ...;
  return aYear[max_idx];
}    

答案 2 :(得分:1)

回答你的问题:

foo(x) = 9;   // is this wrong?

我会说是的,它是错误的,虽然它在语法上是有效的,但没有意义。至于你的“考试”问题(谁在问这些东西?):

Week & Week::highestSalesWeek(Week aYear[52])
{
  Week max = aYear[0];
  for(int i = 1; i < 52; i++)
  {
    if (aYear[i].getSales() > max.getSales()) max = aYear[i];
  }
  return max;
}

好吧,在参数上提供数组维度是没有意义的,代码显然应该使用向量。并且校正应该在函数的签名中:

Week  Week::highestSalesWeek(Week aYear[52])

换句话说 - 返回一个值。您应该几乎总是返回值而不是引用 - 引用是用于函数参数。