Как вызвать неконстантную функцию внутри константной функции (C ++) - PullRequest
20 голосов
/ 15 февраля 2011

У меня есть устаревшая функция, которая выглядит следующим образом:

int Random() const
{
  return var_ ? 4 : 0;
}

, и мне нужно вызвать функцию в этом устаревшем коде, чтобы она теперь выглядела так:

int Random() const
{
  return var_ ? newCall(4) : 0;
}

Проблема в том, что я получаю эту ошибку:

In member function 'virtual int Random() const':
class.cc:145: error: passing 'const int' as 'this' argument of 'int newCall(int)' discards qualifiers

Теперь я знаю, чтобы исправить эту ошибку, я могу сделать мою newCall() константной функцией.Но затем у меня есть несколько вызовов funciton в newCall(), которые я должен сделать, поэтому теперь мне нужно сделать все эти вызовы функций постоянными.И так далее, и так далее, пока в конце концов я не почувствую, что половина моей программы будет постоянной.

Мой вопрос: есть ли способ вызвать функцию в Random (), которая не является const?Или у кого-нибудь есть идеи о том, как реализовать newCall() в Random(), не делая половину моей программы постоянной.

Спасибо

-josh

Ответы [ 7 ]

19 голосов
/ 15 февраля 2011

Вы должны изменить вашу программу для правильного использования / объявления const ...

одна альтернатива - использовать const_cast.

16 голосов
/ 15 февраля 2011
int Random() const
{
  return var_ ? const_cast<ClassType*>(this)->newCall(4) : 0;
}

Но это не очень хорошая идея.Избегайте, если это возможно!

1 голос
/ 15 февраля 2011

Здесь есть две возможности. Во-первых, newCall и ВСЕ его вызываемые на самом деле являются немодифицирующими функциями. В этом случае вы должны обязательно пройти и отметить их все const. И вы, и будущие разработчики кода будут благодарны вам за то, что вы сделали его намного проще для чтения кода (исходя из личного опыта здесь). Во-вторых, newCall фактически изменяет состояние вашего объекта (возможно, через одну из функций, которые он вызывает). В этом случае вам нужно сломать API и сделать Random неконстантным, чтобы правильно указать вызывающим абонентам, что он изменяет состояние объекта (если изменения влияют только на физическое постоянство, а не на логическое постоянство, вы можете использовать изменяемые атрибуты и распространять const ).

1 голос
/ 15 февраля 2011
const_cast<MyClass *>(this)->newCall(4)

Делайте это только если вы уверены, что newCall не изменит "this".

0 голосов
/ 15 февраля 2011

если это действительно генератор случайных чисел, то код / ​​состояние генерации чисел, вероятно, может быть помещен в локальный статический генератор класса.Таким образом, ваш объект не видоизменяется, и метод может оставаться постоянным.

0 голосов
/ 15 февраля 2011

Спецификатор const утверждает, что экземпляр this класса будет неизменным после операции, что компилятор не может автоматически определить.

const_cast можно использовать, но это зло

0 голосов
/ 15 февраля 2011

Не используя константные приведения, не могли бы вы попытаться создать новый экземпляр класса в методе Random()?

...