Я пытаюсь вызвать функцию для полиморфного элемента. Но я получаю следующее сообщение об ошибке во время компиляции:
'
this
' argument to member function 'select
' has type 'const SelectParam
', but function is not markedconst
ошибка отображается при p->selection(*it)
std::set<Tuple>::iterator it;
for (it = tuples.begin(); it != tuples.end();) {
for (const SelectParam* p: selectionParams) {
bool successful = p->select(*it);
if ( !successful ) {
it = tuples.erase(it);
} else {
it++;
}
}
}
и вот как определяются эти классы. (Раньше у меня не было всех констант и &, но я помещал их везде, где мог, в надежде, что я сделаю все, что мне нужно, константой, но ясно, что я неправильно подхожу к проблеме, поскольку это ничего не меняет.
В одном из дочерних классов, который хранится по родительскому указателю.
bool const select(Tuple const & tup) {
bool matched = false;
if (tup[idx] == val) {
matched = true;
}
return matched;
}
В другом дочернем классе, который используется с полиморфизмом
bool const select(Tuple const & tup) {
bool matched = false;
if (tup[idx1] == tup[idx2]) {
matched = true;
}
return matched;
}
И, наконец, вот супер простой родительский класс.
class SelectParam {
public:
virtual const bool select( Tuple const & t) = 0;
};
Заранее спасибо за желание помочь моему слабому мозгу.
Вам нужно явно указать компилятору, что ваша функция не будет изменять никаких членов:
bool const select(Tuple const & tup) const {
Действительно, вы не можете назвать не-const
метод const
объектом. Но вы также не можете вызвать метод, отличный от const
, через указатель или ссылка к объекту const
(независимо от того, является ли упомянутый объект const
или нет).
Это означает, что это:
const SelectParam* ptr = whatever();
ptr->select(someTuple);
плохо сформирован.
В вашем случае вы объявили указатель на const SelectParam
здесь, в этой строке:
for (const SelectParam* p: selectionParams) {
Просто уберите const
и все должно заработать :-)
С другой стороны, если select
никогда не предназначено для изменения объекта, просто пометьте его как const:
virtual const bool select( Tuple const & t) const = 0;
И ваш код тоже должен работать.
Объект, объявленный как const
, не может быть изменен ни const
, ни функцией-членом non-const
(за исключением конструктора и деструктора). Даже если он передается по ссылке. Из этого правила есть два исключения:
const
-ность можно отбросить (отбросить константу), но обычно это не рекомендуется.mutable
. Эти члены могут быть изменены с помощью функций-членов, даже если содержащий объект объявлен const
.Подробнее можно прочитать здесь:
const object - an object whose type is const-qualified, or a non-mutable subobject of a const object. Such object cannot be modified: attempt to do so directly is a compile-time error, and attempt to do so indirectly (e.g., by modifying the const object through a reference or pointer to non-const type) results in undefined behavior.
Как прокомментировали другие, одним из решений было бы добавить ключевое слово const
к функции-члену как в ее объявлении а также, так и в определении. При этом функцию можно вызывать даже на const
объектах.
А что не так с this
?
Внутри функции-члена this
— это указатель на текущий объект, для которого была вызвана функция [видеть].