У меня есть этот код:
class C
{
virtual vec3 f1(const A* a, B* b){...}
virtual vec3 f2(A const* a, B const* b)
{
vec3 color = f1(a, b);
...
}
}
Я хочу вызвать f1
из f2
, но я не знаю, как правильно передать b. Теперь при компиляции я получаю:
error: invalid conversion from 'const B*' to 'B* [-fpermissive]'
Я пробовал vec3 color = f1(a, const_cast<B *>(b));
Это компилируется, но затем я получаю ошибку сегментации при выполнении.
Обратите внимание, что я не могу изменить подпись функции. Я также не могу изменить определение A
или B
для реализации функции getCopy()
например.
ОБНОВИТЬ:
Я нашел функцию, которая возвращает измененную копию b, поэтому моя проблема решена. Спасибо вам всем за то, что убедили меня перестать пытаться использовать его прямо в f1.
Если вы не можете изменить сигнатуры функций, вы не сможете решить вашу проблему. Логически f2
заключает контракт с вызывающим: "Я возьму B * и использую его, но я гарантирую, что не буду изменять B
указывающий на". Если вы затем передадите этот указатель на что-то еще, что модифицирует B
вы нарушили контракт. Если f2
предназначен для изменения B
, то B*
он принимает, не должен быть const
(и, возможно, он должен быть B&
, как побочная заметка).
А что касается сбоя: изменение объекта, первоначально объявленного как const
является неопределенным поведением. Реально это означает, что компилятор может свободно делать что-то вроде хранения в памяти только для чтения и других сложных вещей. Если вы затем попытаетесь написать на него, все ставки будут отключены. Он может потерпеть крах. Он может работать. Все может случиться.
Единственным логическим решением было бы
virtual vec3 f2(A const* a, B const* b)
{
B mutableB(*b);
vec3 color = f1(a, &mutableB);
...
}
Время выполнения бесплатное для сбоя, потому что изменение ранее объявленной переменной const
после того, как const_cast
является неопределенным поведением. И я предполагаю, что b
изначально const
, и f1
пытается его модифицировать.
Подумайте об этом из компилятора POV: вам нужны две функции - f1
и f2
. Вы можете передавать постоянные параметры в f2
, тем самым гарантируя, что вы не собираетесь их изменять. Но тогда вы пытаетесь передать их f1
, который может их модифицировать.
Если f1
изменяет цель указателя, то и f2
; поэтому f2
не может принимать указатель на объект const
. Вам придется удалить const
из f2
и не пытаться вызвать его с помощью постоянного объекта. Вам не разрешается изменять объекты const
, и при попытке программа может сработать (или иначе иметь неопределенное поведение).
Если f1
не изменяет его, измените этот указатель на const
. Похоже, это так.