const char * en paramètre de la fonction en C++
NOTE: je sais qu'il y a de nombreuses questions qui en ont parlé, mais je suis encore un débutant et je ne pouvais pas comprendre les exemples.
J'ai eu un prototype de fonction qui va comme ceci:
int someFunction(const char * sm);
Ici, comme vous le savez, const char* signifie que cette fonction peut accepter const ou non-const de pointeur vers char. J'ai essayé quelque chose comme ça dans le corps de la fonction:
someMemberVar = sm;
someMemberVar est juste un pointeur vers char. Le compilateur me donne une erreur me disant:
impossible de convertir de const char* char*.
Ici, je n'avais pas passer une constante, de sorte que soit sm ou someMemberVar ne sont pas constantes. Donc, ce constant, le compilateur est en train de parler?
- Comment exactement est
someMemberVar
déclaré, et quel est le message d'erreur exact que vous obtenez (celui que vous fournissez ne fait aucun sens, donc je pense qu'il y est une faute de frappe là). - J'ai corrigé mon erreur. Elle est déclarée comme ça: char * someMemberVar;
- il est la plupart du temps correct. char* peut être en toute sécurité en fonte à const char*, de sorte que vous pouvez passer un char* à cette méthode, tout comme vous le feriez d'un const char*. Le compilateur va juste faire le casting pour vous.
- Non, il peut accepter const char * ou char *. Il va les traiter comme si elles étaient const char *. Vous avez besoin d'un cast explicite pour changer un const type de données à un non-const, mais pas dans l'autre sens. Après tout, juste parce que une variable peut être écrit pour ne pas dire que j'ai du changer sa valeur.
- Si vous avez besoin de comprendre ce qui se passe ici, pour d'autres raisons, la solution réelle, il est probable que vous voulez est de faire
someMemberVar
unstd::string
. Surtout quand vous êtes en train d'apprendre les rudiments de la langue, les variables qui détiennent des valeurs (comme int, string, etc.) sont plus faciles à utiliser. Après avoir appris la langue, ils sont encore plus faciles à utiliser (parce que vous /souhaitez/ pour contenir une valeur, la plupart du temps).
Vous devez vous connecter pour publier un commentaire.
Je vais essayer de mettre en termes simples ce que les autres disent:
La fonction
someFunction
prend une chaîne en lecture seule (par souci de simplicité, sichar *
pourrait être utilisé dans des dizaines d'autres cas). Si vous passez en lecture seule chaîne àsomeFunction
ou pas, le paramètre est traité comme étant en lecture seule par le code en cours d'exécution dans le contexte de cette fonction. Au sein de cette fonction, par conséquent, le compilateur va essayer de vous empêcher de vous écrire à cette chaîne autant que possible. Un non-const pointeur est une telle tentative d'ignorer la lecture seule balise à la chaîne et le compilateur, à juste titre, et à haute voix vous informe de ce mépris pour son type de système d' 😉La première est une fonction qui prend un paramètre en lecture seule. La deuxième
const
écrit après la fermeture de parenthèses est valable uniquement pour les fonctions de membres. Il ne prend pas seulement un paramètre en lecture seule, mais aussi garantit de ne pas modifier l'état de l'objet. C'est généralement appelé niveau de la conception de const.const
", c'est qu'il s'applique àthis
. Dans un non-const méthode de classeT
, le type dethis
estT* const
. Dans un const méthode de la même classe, le type dethis
estT const* const
.Il n'est pas tout à fait clair à partir de votre question, et je soupçonne que le texte de l'erreur que vous donnez est en fait mal, et en fait, on lit:
Puisque vous dites que
Cela fait sens. Gardez à l'esprit que
const char*
est en fait le même quechar const*
- qui est, il est un pointeur vers un const char, pas un const pointeur vers char! Et vous ne pouvez pas convertir un pointeur versT const
à un pointeur sur unT
, parce que les sauts de sécurité de type. Considérer:const char*
est un pointeur constant de char:Si vous passez un non-const pointeur vers
someFunction
, il est automatiquement converti en un pointeur const. Si vous ne pouvez pas affecter desm
àsomeMemberVar
parce que cela violerait la constness de sm. Vous pouvez déclarersomeMemberVar
comme unconst char*
et votre code va fonctionner, cependant, vous ne pouvez pas modifier ce qu'il souligné.Dans un commentaire de l'un de l'autre les réponses que vous avez dit:
Entre votre question de départ, et que ce commentaire je pense que vous êtes l'incompréhension comment le compilateur traite les types.
Vous êtes correct de dire qu'une non-const
char *
peut être coulé en toute sécurité à uneconst char *
. Cependant, votre méthode est explicitement prise d'unconst char *
. Ainsi, alors que vous pouvez passer unchar *
dans la fonction, le compilateur simplement jette automatiquement l'argument lors de l'appel de fonction. Le code dans la fonction ne sais pas si l'argument d'origine a été const ou non. Le compilateur doit passer par la déclaration de la variable que vous utilisez, pas précédentes à la variable qui a la même valeur.Si vous voulez être en mesure de traiter les non-const
char *
variables différemment (assigner), alors vous aurez besoin de définir une fonction qui prend un non-constchar *
variables.const char * sm est un pointeur vers une constante caractère (ou un tableau). Lorsque vous essayez d'affecter, someMemberVar, un pointeur vers char, vous essayez de la faire pointer vers un ensemble de constante caractères. C'est la cause de l'erreur.
Dans votre exemple, sm est const char* donc someFunction a un contrat avec l'appelant qu'il ne modifiera pas la mémoire sm points à.
Mais si vous affectez sm pour someMemberVar et someMemberVar n'est pas const char* vous serez alors en mesure de modifier la mémoire sm points via someMemberVar et le compilateur ne vous permettra pas de le faire.