Я делаю что-то не так здесь (ссылки в C++)?

Я играл вокруг со ссылками (у меня все еще есть проблемы в этом отношении).

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

Это корректно/достаточно?

5
задан m4design 12 June 2010 в 22:21
поделиться

3 ответа

Первый правильный.

Для второго существует бесконечное количество решений :), но это будет мое:

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; 
} 
5
ответ дан 14 December 2019 в 04:30
поделиться

В ссылках всегда важно следить за тем, чтобы ссылка не на объект, который вышел за пределы области видимости.

Это проблема вашего второго примера:

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

max - автоматическая переменная, локальная для этого метода. Когда этот метод выходит за рамки, max выходит за рамки, и теперь ваш код имеет ссылку на случайную память.

Поскольку ваш код хочет продолжать переназначать max , вы не можете использовать ссылку (поскольку после начального назначения вы можете изменять только то, на что ссылаетесь, но не саму ссылку). Вам необходимо отслеживать фактическую часть года , на которую вы хотите вернуть ссылку. Два предложения.

// 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
ответ дан 14 December 2019 в 04:30
поделиться

Чтобы ответить на ваши вопросы:

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])

Другими словами - вернуть значение. Вы почти всегда должны возвращать значения, а не ссылки - ссылки предназначены для параметров функции.

1
ответ дан 14 December 2019 в 04:30
поделиться
Другие вопросы по тегам:

Похожие вопросы: