Странная ошибка C ++: test.cpp: 15: ошибка: передача «const *» в качестве «this» аргумента «*» отменяет квалификаторы - PullRequest
43 голосов
/ 15 февраля 2009

У меня возникли некоторые проблемы с определенным фрагментом кода. Если кто-нибудь сможет просветить меня в этом вопросе, это будет с благодарностью, я выделил проблему в следующем примере:

#include <iostream>

using namespace std;

class testing{
   int test();
   int test1(const testing& test2);
};

int testing::test(){
   return 1;
}

int testing::test1(const testing& test2){
   test2.test();
   return 1;
}

Итак, что могло вызвать следующую ошибку:

test.cpp: 15: ошибка: передача «const testing» в качестве аргумента «this» для int testing :: test () ’отбрасывает квалификаторы

Большое спасибо!

Ответы [ 5 ]

67 голосов
/ 15 февраля 2009

Проблема заключается в вызове не const функции test2.test() для const объекта test2 из testing::test1.

testing::test1 получает test2 в качестве параметра const testing &test2. Так в пределах testing::test1, test2const. Затем в первой строке функции:

test2.test()

Функция testing::test вызывается на test2. Эта функция не объявлена ​​с const в конце подписи, поэтому она может изменять объект, к которому она вызывается (указатель this неявно передается ей), и даже если это не так, компилятор предполагает это. Позволяя вам вызывать его там, компилятор позволит вам изменить переменную const без явного преобразования, которое C ++ не должно допускать. Поэтому объяснить сообщение об ошибке :

test.cpp:15: error: passing ‘const testing’ as ‘this’ argument of ‘int testing::test()’ discards qualifiers

this относится к объекту, над которым работает функция-член (testing::test), и в этом случае это не const, потому что testing::test не был объявлен с const, и, таким образом, обнаружено несоответствие при попытке сделать указатель не const (this) ссылается на объект const (testing), игнорируя квалификатор const .

Чтобы решить эту проблему , решите, должна ли когда-либо функция testing::test изменять объект, к которому она обращена (как это пишется сейчас, она не делает, поскольку все, что она делает, это return 1 Тем не менее, это может измениться, поэтому вам нужно подумать о том, какова его предполагаемая функциональность). Если это так, то, очевидно, вызов его для объекта const - это плохо, хотя вы можете использовать const_cast, чтобы попросить компилятор переопределить это, но это опасно. Если это не так, отметьте его const, чтобы его можно было вызывать и для const объектов:

class testing{
    int test1() const;
    // ...
}

int testing::test() const {
    // ...
}
5 голосов
/ 15 февраля 2009

Из-за определения функции-члена test1:

int testing::test1(const testing& test2){
   test2.test();
   return 1;
}

Вы передаете константную ссылку для переменной test2.

Это означает, что вы не можете изменить ни одного члена test2 и не можете вызвать любую функцию-член, которая не является константной или не является статической.

Вот как это можно исправить:

int testing::test() const {
   return 1;
}

Дополнительная константа в конце сообщает компилятору, что вы не планируете изменять содержимое текущего объекта (и если вы это сделаете, вы получите другую ошибку компиляции).

2 голосов
/ 15 февраля 2009

Строка: test2.test ()

вызывает неконстантную функцию, даже если test2 является константной ссылкой. Это проблема. Вы можете исправить это, сделав test :: test const функцией.

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

testing :: test1 (const testing & test2) ожидает, что переданный объект будет const, и он выдаст ошибку, если вы либо измените значения его переменных, либо получите доступ к любым их методам, которые явно не определены как const .

Поскольку метод test () фактически не меняет никаких данных, рекомендуется установить их const следующим образом:

class testing{
   int test() const;
   int test1(const testing& test2);
};

int testing::test() const {
   return 1;
}

В качестве альтернативы просто удалите слово const при определении аргументов для test1 (), и это позволит вам получить доступ к любому из методов переданного объекта на досуге.

0 голосов
/ 26 мая 2015

Для быстрого и удобного решения попробуйте скомпилировать с -fpermissive, как это часто предлагается самим компилятором (что, вероятно, и делают компиляторы VisualStudio, поскольку пользователи Windows редко сообщают об этой проблеме).

...