web-dev-qa-db-fra.com

Une erreur C ++ étrange: test.cpp: 15: erreur: passer «const *» comme argument «this» de «*» rejette les qualificatifs

J'ai des problèmes avec un morceau de code particulier, si quelqu'un peut m'éclairer à ce sujet, ce serait grandement apprécié, j'ai isolé le problème dans l'exemple suivant:

#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;
}

Alors, qu'est-ce qui pourrait éventuellement provoquer l'erreur suivante:

test.cpp: 15: erreur: passer "const testing" comme argument "this" de "int testing :: test ()" élimine les qualificatifs

Merci beaucoup!

43
FurtiveFelon

Le problème appelle une fonction non - consttest2.test() sur un objet consttest2 de testing::test1.

testing::test1 obtient test2 comme paramètre const testing &test2. Donc dans testing::test1, test2const. Puis dans la première ligne de la fonction:

test2.test()

Le testing::test la fonction est appelée test2. Cette fonction n'est pas déclarée avec const à la fin de la signature, elle peut donc modifier l'objet auquel elle est appelée (le pointeur this lui est implicitement transmis), et même si ce n'est pas le cas, le le compilateur le suppose. En vous permettant de l'appeler là, le compilateur vous permettrait de modifier une variable const sans transtypage explicite, ce que C++ n'est pas censé autoriser. Par conséquent pour expliquer le message d'erreur:

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

this fait référence à l'objet de la fonction membre (testing::test) fonctionne, et dans ce cas, ce n'est pas const, car testing::test n'a pas été déclaré avec const, et donc la non-concordance est détectée lorsque vous essayez de faire un pointeur non - const (this) faire référence à un const (testing), en ignorant le qualificatif const.

Pour résoudre ce problème, décidez si le testing::test la fonction doit toujours avoir besoin de modifier l'objet sur lequel elle est appelée (la façon dont elle est écrite maintenant ne le fait pas, comme tout ce qu'elle fait est return 1, mais cela peut changer, vous devez donc réfléchir à ses fonctionnalités prévues). Si c'est le cas, alors évidemment l'appeler sur un objet const est mauvais, bien que vous puissiez utiliser const_cast pour demander au compilateur de remplacer cela, mais c'est dangereux. Si ce n'est pas le cas, marquez-le const, afin qu'il puisse également être appelé sur des objets const:

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

int testing::test() const {
    // ...
}
68
Tom Alsberg

En raison de la définition de la fonction membre test1:

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

Vous passez une référence const pour la variable test2.

Cela signifie que vous ne pouvez modifier aucun membre de test2 et vous ne pouvez appeler aucune fonction membre qui n'est pas const ou qui n'est pas statique.

Voici comment résoudre ce problème:

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

Le const supplémentaire à la fin indique au compilateur que vous ne prévoyez pas de modifier le contenu de l'objet actuel (et si vous le faites, vous obtiendrez une erreur de compilation différente).

5
Brian R. Bondy

La ligne: test2.test ()

appelle une fonction non const, même si test2 est une référence const. C'est le problème. Vous pouvez résoudre ce problème en faisant de testing :: test une fonction const.

2
Himadri Choudhury

testing :: test1 (const testing & test2) s'attend à ce que l'objet passé soit const, et il vous donnera une erreur si vous modifiez les valeurs de ses variables, ou accédez à ses méthodes qui ne sont pas explicitement définies comme const.

Étant donné que la méthode test () ne modifie en fait aucune donnée, la meilleure pratique consiste à la définir const, comme suit:

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

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

Sinon, supprimez simplement la constante Word lors de la définition des arguments de test1 (), et cela vous permettra d'accéder à n'importe quelle méthode de l'objet passé à votre guise.

1
goldPseudo