55 votes

Impossible de convertir le pointeur 'this' de 'const Line' en explication 'Line &' ?

Cette méthode :

bool Point::Intersects(const Line& line) const {
    return (line.ContainsPoint(*this, false));
}

provoque l'erreur suivante : impossible de convertir le pointeur 'this' de 'const Line' en 'Line &'. Cette modification :

bool Point::Intersects(const Line& line) const {
    return const_cast<Line&>(line).ContainsPoint(*this, false);
}

répare l'erreur, mais ne semble pas être la bonne façon de résoudre le problème. Pourquoi la méthode originale est-elle considérée comme une erreur ?

Si ça peut aider, ContainsPoint(const Point& point, bool isInfinite) est non-const et toutes les méthodes qu'il appelle sont également non-const.

69voto

Ken Wayne VanderLinde Points 9054

Vous avez en fait fourni la réponse vous-même, dans un sens.

Dans votre Intersects le paramètre line est déclaré const . Cela limite la façon dont vous pouvez utiliser cette variable. Plus précisément, vous pouvez uniquement appeler const et vous ne pouvez le passer qu'aux méthodes qui attendent un const Objet en ligne.

Cependant, vous avez souligné que ContainsPoint n'est pas déclaré const . Il ne satisfait donc pas à l'exigence mentionnée ci-dessus (c'est-à-dire l'appel d'une fonction non-START). const sur un const n'est pas autorisé). C'est la raison pour laquelle la méthode originale génère l'erreur, et cela explique également pourquoi votre deuxième version fonctionne, puisque la restriction est allégée via l'élément const_cast .

Le véritable problème réside dans la déclaration de ContainsPoint (et probablement aussi avec toutes les méthodes qu'il appelle, puisqu'elles ne sont pas non plus des méthodes de l'UE). const ). Il semble y avoir un gros défaut de conception ici. Puisque le but de ContainsPoint consiste à vérifier si un Point est sur un Line les effets secondaires seront inattendus. Il n'y a donc aucune raison pour qu'il ne soit pas une const méthode. En fait (et votre exemple le démontre), les utilisateurs de Line serait s'attendre à ContainsPoint pour être un const méthode. Par conséquent, la véritable solution consiste à modifier la conception de la Line de sorte que des méthodes comme ContainsPoint sont déclarés const et seules les méthodes qui modifient clairement l'état d'une instance sont laissées sans objet. const

7voto

Andrew White Points 23508

Dans ce cas, vous appelez une méthode non constante sur une référence constante, ce qui n'est pas autorisé. Vous avez deux possibilités :

  1. Fais ce que tu as fait et const_cast
  2. Faire ContainsPoint une méthode constante

2voto

Adrian Shum Points 10784

Le problème est en fait très simple :

vous avez une classe A, avec un non-const foo(), vous invoquez une méthode non-const foo() par le biais d'une référence à const A.

const A& a = ...;
a.foo();  // failed

C'est le but de const : une variable const signifie qu'elle est déclarée comme ne devant pas être modifiée. Alors que foo() "va se modifier" (puisque foo() est une méthode non const, ce qui signifie : "Je suis autorisé à changer quelque chose à l'intérieur"), c'est pourquoi le compilateur se plaint : vous avez une const var (a), mais vous allez changer son contenu (à travers foo()).

La solution est simple, mais vous devez savoir quelle est la bonne façon de procéder :

1) Si vous êtes sûr que foo() peut être invoquée par le biais de const ref etc, vous devez la déclarer comme une méthode const : A::foo() const {...}

2) Si vous savez que foo() n'est pas approprié pour faire du const, vous devriez considérer

2.1) revoir "a" pour voir s'il est plus approprié de faire du non-const, ou

2.2) trouver une autre méthode const en A qui a fait le travail.

(Il existe d'autres moyens comme l'utilisation de mutable ou de const_cast, mais ce n'est pas la meilleure solution dans 99,9% des cas. Je ne l'ai donc pas mentionné ici)

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