J'ai créé un pointeur const qui pointe vers une instance d'abject allouée dynamiquement.Je ne pouvais pas comprendre que l'objet lui-même est const ou non.
J'ai d'abord essayé d'appeler une fonction membre non-const en utilisant le pointeur, comme prévu cela a provoqué une erreur de compilation car (c'est mon explication, je ne sais pas si c'est vrai ou non) ce pointeur créé par la fonction membre est assigné à ce pointeur const. Cela n'a rien donné.
Deuxièmement, j'ai essayé de déréférencer le pointeur et d'appeler cette fonction membre non-const. Je pensais que ce pointeur créé par la fonction membre ne sera plus un pointeur const car la compilation ne peut pas connaître l'objet retourné par p
(à savoir * p
) est retourné par un pointeur const ou non. Il s'avère que je me suis trompé.
Comment la fonction membre comprend-elle cela?
Je pensais que la ligne étiquetée 2 ne créera pas de compilation Erreur. Cela provoque une erreur de compilation. Le message d'erreur est:
"a.cpp: In function âint main()â: a.cpp:21:13: error: passing âconst Aâ as âthisâ argument discards qualifiers [-fpermissive] p->print(); //1 causes compile error ^ a.cpp:10:9: note: in call to âvoid A::print()â void print() ^~~~~ a.cpp:22:15: error: passing âconst Aâ as âthisâ argument discards qualifiers [-fpermissive] (*p).print(); //2 causes compile error ^ a.cpp:10:9: note: in call to âvoid A::print()â void print() ^~~~~
#include<iostream> class A { int a=4; public: A() {} void print() { std::cout<<a<<std::endl; } }; int main() { const A* p = new A(); p->print(); //1 causes compile error (*p).print(); //2 causes compile error return 0; }
3 Réponses :
Les variables ont des types et peuvent donc être const ou non const, mais les expressions ont aussi des types. Le type de (* p)
est const A
, et vous ne pouvez pas appeler une méthode non-const d'un type const.
Hmm vous dites que l'objet créé par new est const? Pourquoi parce que je peux pointer un pointeur entier const vers un entier non const. Y a-t-il une raison ? ---- J'ai eu ma réponse ----
Il n'y a aucune différence entre (1) et (2). (1) est le sucre de syntaxe pour (2). Vous devez définir la méthode d'impression en tant que const afin de l'appeler pour l'objet const.
void print() const { ... }
Comme il a déjà été noté, les expressions ont des types et le type de (* p) est const A. Vous ne pouvez pas appeler une fonction non-const sur un objet de type const mais vous pouvez appeler une fonction membre const. Les fonctions membres peuvent avoir un qualificatif const qui les marquera comme pouvant être invoquées sur des objets const ou des pointeurs vers des objets const.
void print() const { std::cout<<a<<std::endl; }
Cela rendra votre code compilé. et il semble que c'est ce que vous aviez l'intention de faire de toute façon.
Je ne comprends pas de quoi vous êtes confus. Si on déréférence
const A *
, il en resteconst A
, non?p
est un pointeur vers l'objetconst
, tandis queprint
n'est pas marqué comme fonction const. Qu'est-ce qui est surprenant?@SergeyA C'est surprenant si vous pensez que l'exactitude de const est appliquée sur la base d'une expression primaire plutôt que par le biais du système de types.
alors const A * p = nouveau A (); et const A * p = new const A (); n'a pas de différence non?
Ils sont légèrement différents, mais pas d’une manière particulièrement utile, et je n’ai jamais vu
new const A
en code réel. Voir stackoverflow.com/questions/1927477/… .pourquoi l'objet créé est-il converti en type const? Je veux dire que je crée un entier non const et un entier const qui pointe vers cet entier.
Parce que vous l'avez fait lorsque vous l'avez affecté à une variable de type
const A *
. C ++ vous permet de convertir implicitement un objet non const en type const, car c'est une chose totalement sûre à faire.@Sneftel merci, maintenant je comprends :)
veuillez inclure les messages d'erreur textuellement au lieu de les paraphraser. L'appeler "classique" est un peu déplacé à mon humble avis, qu'est-ce qui est classique à ce sujet?
@ formerlyknownas_463035818 okey