Подтвердить что ты не робот

Не удается преобразовать указатель 'this' из строки "const Line" в "Line &"?

Этот метод:

bool Point::Intersects(const Line& line) const {
    return (line.ContainsPoint(*this, false));
}

вызывает эту ошибку: не может преобразовать указатель 'this' из 'const Line' в 'Line &' Это изменение:

bool Point::Intersects(const Line& line) const {
    return const_cast<Line&>(line).ContainsPoint(*this, false);
}

исправляет ошибку, но не кажется правильным способом устранить проблему. Почему исходный метод считается ошибкой?

Если это помогает, ContainsPoint(const Point& point, bool isInfinite) не является константой, и все методы, которые он вызывает, также не являются константами.

4b9b3361

Ответ 1

Фактически вы сами дали ответ, в каком-то смысле.

В вашем методе Intersects параметр line объявляется const. Это ограничивает использование этой переменной. В частности, вы можете называть только теги const, и вы можете передать их только методам, ожидающим объект const Line.

Однако вы указали, что ContainsPoint не объявлен const. Поэтому он не удовлетворяет упомянутому выше требованию (т.е. Вызов метода const для объекта const не допускается). Вот почему исходный метод генерирует ошибку, а также объясняет, почему ваша вторая версия работает, поскольку ограничение облегчается с помощью const_cast.

Реальная проблема заключается в объявлении ContainsPoint (и, вероятно, также с любыми методами, которые он вызывает, поскольку они также не являются константами). Здесь, по-видимому, большой недостаток дизайна. Поскольку целью ContainsPoint является проверка того, будет ли a Point на побочных эффектах line неожиданным. Поэтому не должно быть никаких оснований для этого не быть методом const. Фактически (и ваш пример показывает это) пользователи line ожидали бы ContainsPoint как метод const. Поэтому реальное решение состоит в изменении дизайна класса line, так что такие методы, как ContainsPoint, объявляются const, и только методы, которые явно изменяют состояние экземпляра, остаются не const

Ответ 2

В этом случае вы вызываете метод non-const для ссылки const, которая недопустима. У вас есть два варианта:

  • Сделайте то, что вы сделали, и const_cast
  • Сделать ContainsPoint метод const

Ответ 3

Проблема на самом деле простая:

у вас есть класс A с методом не const foo(), вы вызываете неконстантный метод foo() через ref для const A.

const A& a = ...;
a.foo();  // failed

То, что const предназначалось для: константной переменной, означает, что она не будет изменена. Хотя foo() "собирается изменить себя" (поскольку foo() является неконстантным методом, что означает: "Я прав, чтобы изменить вещь внутри" ), поэтому компилятор жалуется: у вас есть константа var (a), но вы собираетесь изменить его содержимое (через foo())

Способ решения - прямолинейный, но вы должны знать, какой путь правильный:

1) Если вы уверены, что foo() должен быть законным для вызова через const ref и т.д., вы должны объявить его как метод const: A:: foo() const {...}

2) Если вы знаете, что foo() не подходит для создания const, вы должны рассмотреть

2.1) просмотрите "a", чтобы увидеть, более уместно ли сделать неконстантный, или

2.2) найти другой метод const в A, который выполнил работу.

(Есть и другой способ, например, использовать mutable или const_cast, но это не способ пойти на 99,9% времени. Поэтому я не упоминал здесь)