#c
#c
Вопрос:
У меня есть класс
class Test {
public:
void f() {}
void g() const { f(); }
};
который не может скомпилироваться с
ошибка: передача ‘const Test’ в качестве аргумента ‘this’ отбрасывает квалификаторы (при вызове void Test ::f())
Я понимаю, что я не должен вызывать неконстантный f
из const g
. Однако я не понимаю содержания сообщения. Откуда берется const Test
объект и какие квалификаторы отбрасываются ( f()
не имеет никаких квалификаторов)??
Комментарии:
1.
this
Указатель передается в функции-члены автоматически (какself
в python). Вероятно, вы вызвалиconst
функцию-членg
, внутри которой вы вызываете неконстантную функцию-членf
.2. @Yashas: спасибо. Я так и подозревал, но почему это
const Test
указатель.const
преобразует ли функция-член это автоматически??3.
const
квалификатор в функциях-членах применяется к этому экземпляру объекта, а не к самой функции4. @Yashas Опять же, не отвечайте в разделе комментариев. Наведите курсор мыши на ссылку «добавить комментарий» (или прочитайте заголовок раздела ниже), если вы мне не верите.
5. Действительно. Ответы в разделе ответов, пожалуйста, @Yashas.
Ответ №1:
this
Указатель в const
функции-члене имеет тип const Test*
. Вот как const
логически обеспечивается доступ только для участников. Это своего рода деталь реализации, но довольно разумная.
Когда вы пытаетесь вызвать f()
, думайте об этом как о передаваемом аргументе скрытой функции. Аргументом скрытой функции является this
указатель. f()
ожидает Test*
, но вы передаете его const Test*
. Преобразование между ними привело бы к «отбрасыванию квалификаторов», т. Е. пришлось бы отбросить const
, что недопустимо.
Я согласен с вами, что диагностика немного эзотерична, но в основном это всегда означает «вы пытаетесь сделать не- const
вещь в const
контексте».
Комментарии:
1. Да, приятно иметь ответы в разделе ответов, поскольку их можно рецензировать. На мой взгляд, это хороший ответ. Проголосуйте за.
2. @спасибо. Когда я вызываю функцию const для неконстантного объекта, откуда берется
const Test *
?this
создается для вызова функции??3. @blue_note Да, точно, это волшебный указатель, который вы получаете бесплатно автоматически. (В конечном счете, это действительно «исходит» с сайта вызова, где вы указали объект для вызова функции, с
const
дополнительным добавлением по пути, если этоconst
вызванная вами функция)4. @Bathsheba Все реже рискует публиковать ответы здесь. Я действительно не понимаю. Не может быть проще! Некоторые другие сайты SE действительно расправились с этим, но SO по какой-то причине сопротивляется. : (Лично я думаю, что иметь аккуратный дом более гостеприимно, чем большой старый беспорядок
Ответ №2:
Невозможно 1 вызвать f()
из g()
как g()
есть const
(что означает, что неявный this
указатель является const
), а f()
нет const
.
Следовательно, компиляция завершается неудачей, в вашем случае с полезной диагностикой.
1 Ну, не совсем невозможно: взлом, поведение которого могло быть неопределенным, если объект был создан как const
есть
void g() const { const_cast<Test*>(this)->f(); }