简体   繁体   中英

Am I doing something wrong here (references in C++)?

I've been playing around with references (I'm still having issues in this regard).

1- I would like to know if this is an acceptable code:

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- Also this is from an exam sample:

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;
}

It asks about the mistake in this code, also how to fix it.

My guess is that it return a local reference. The fix is:

Week & max = aYear[0];

Is this correct/enough?

The first one is correct.

For the second one, there are infinite number of solutions :), but this would be mine:

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; 
} 

If max is a reference, you would modify the first element of aYear everytime you do:

max = aYear[i]

Also, you could use a pointer to return a reference to the week:

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; 
} 

The important thing about references is always making sure that the reference is not to an object that has gone out of scope.

That is the problem with your second example:

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

max is an automatic variable local to that method. When that method goes out of scope, max goes out of scope and now your code has a reference to random memory.

Since your code wants to keep reassigning max , you can't use a reference (since after the initial assignment, you can only modify what is referenced, not the reference itself). You need to keep track the actual part of aYear that you want to return a reference to. Two suggestions.

// 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];
}    

To answer your questions:

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

I would say yes, it is wrong in that it does not make sense although it is syntactically valid. And as for your "exam" question (who is asking this stuff?):

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;
}

Well, providing the array dimension on the parameter is pointless, and the code should obviously use a vector. And the correction should be in the signature of the function:

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

In other words - return a value. You should almost always return values rather than references - references are intended for function parameters.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM