Я играл вокруг со ссылками (у меня все еще есть проблемы в этом отношении).
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];
Это корректно/достаточно?
Первый правильный.
Для второго существует бесконечное количество решений :), но это будет мое:
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;
}
В ссылках всегда важно следить за тем, чтобы ссылка не на объект, который вышел за пределы области видимости.
Это проблема вашего второго примера:
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];
}
Чтобы ответить на ваши вопросы:
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])
Другими словами - вернуть значение. Вы почти всегда должны возвращать значения, а не ссылки - ссылки предназначены для параметров функции.