43 votes

Une erreur étrange en C++ : test.cpp:15: erreur : le passage de « const * » en argument « this » de « * » supprime les qualificateurs

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

#include 

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 aurait pu causer l'erreur suivante :

test.cpp:15: erreur: passer 'const testing' en argument 'this' de 'int testing::test()' supprime les qualificateurs

Merci beaucoup !

69voto

Tom Alsberg Points 3253

Le problème est d'appeler une fonction non-const test2.test() sur un objet const test2 depuis testing::test1.

testing::test1 reçoit test2 en tant que paramètre const testing &test2. Ainsi, à l'intérieur de testing::test1, test2const. Ensuite, dans la première ligne de la fonction :

test2.test()

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

test.cpp:15: erreur: le passage de 'const testing' en tant qu'argument 'this' de 'int testing::test()' supprime les qualificateurs

this fait référence à l'objet sur lequel la fonction membre (testing::test) opère, et dans ce cas, il n'est pas const, car testing::test n'a pas été déclaré avec const, et donc le conflit est détecté lors de la tentative de faire pointer un pointeur non-const (this) vers un objet const (testing), en ignorant le const qualifier.

Pour résoudre cela, décidez si la fonction testing::test doit jamais avoir besoin de modifier l'objet sur lequel elle est appelée (tel qu'elle est écrite actuellement, elle ne le fait pas, car tout ce qu'elle fait est return 1, cependant cela peut changer, donc vous devez réfléchir à quelle est sa fonctionnalité prévue). Si elle doit le faire, alors évidemment l'appeler sur un objet const est mauvais, bien que vous puissiez utiliser const_cast pour demander au compilateur de passer outre, mais c'est dangereux. Si elle ne doit pas le faire, alors marquez-la const, pour qu'elle puisse être appelée sur des objets const également :

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

int testing::test() const {
    // ...
}

5voto

Brian R. Bondy Points 141769

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 constante de la variable test2.

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

Voici comment vous pouvez corriger :

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).

2voto

Himadri Choudhury Points 5300

La ligne : test2.test()

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

1voto

goldPseudo Points 2479

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

Étant donné que la méthode test() ne modifie pas réellement de données, la meilleure pratique est de la déclarer const, comme suit :

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

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

Alternativement, il suffit de supprimer le mot const lors de la définition des arguments pour test1(), ce qui vous permettra d'accéder librement aux méthodes de l'objet passé.

0voto

Naveen Points 37095

Jetez un coup d'œil ici: passer des références const

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X