Почему невозможно преобразовать const X в X &?
Я пытаюсь понять и добиться корректности в проекте Tetris.
Вот рекуррентная проблема, которая возникает у меня, когда я пытаюсь добавить const, где я думаю, что это необходимо.
У меня есть класс (Piece), и один из его закрытых членов класса
Point rotationCenter;
И я пытаюсь написать getter вот так:
inline Point & Piece::getRotationCenter() const
{
return rotationCenter;
}
Раньше у меня был тот же getter, но не как функция const, и он работал. Теперь я получил ошибку C2240 "невозможно преобразовать const Point to Point &".
Что мне делать, чтобы исправить это? Должен ли я оставить getRotationCenter
без const
?
PS: Я читаю https://isocpp.org/wiki/faq/const-correctness как учебник.
Ответы
Ответ 1
Почему невозможно преобразовать const X
в X &
?
Потому что, если это разрешено, становится допустимым следующий опасный код:
const int x = 0;
int& rx = x; // bind const variable to reference (to non-const)
rx = 99; // oops, try to modify the const variable via the reference
Что мне делать, чтобы исправить это? Должен ли я оставить getRotationCenter
без const
?
Это зависит от ваших намерений. Если возвращаемый объект может быть изменен, сделайте функцию-член не константой и верните Point&
. Если нет, то оставьте функцию-член const
и введите тип возврата const Point&
. Функция-член-константа означает обещание, которое не будет изменять (или предоставлять возможность изменения) объекта (и его членов).
Ответ 2
Внутри const
функций-членов все члены данных классов const
. Вы не можете привязать ссылку const
к вашим данным const
, чтобы получить ошибку компилятора.
Если вы не хотите, чтобы ваш вызывающий абонент модифицировал rotationCenter
, вы можете вернуться на Point
или const Point&
.
inline const Point & Piece::getRotationCenter() const
{
return rotationCenter;
}
Если вы хотите, чтобы вызывающий абонент модифицировал rotationCenter
(который я бы вообще не рекомендовал), напишите две перегрузки: одну, которая возвращает Point&
, а другая, которая возвращает const Point&
в зависимости от квалификации объекта, который вы назовите его:
inline Point & Piece::getRotationCenter() //not const
{
return rotationCenter;
}
inline const Point & Piece::getRotationCenter() const
{
return rotationCenter;
}