145 votes

Ce qui ' s le point de pointeurs const ?

Je ne parle pas des pointeurs vers const valeurs, mais const pointeurs eux-mêmes.

Je suis en train d'apprendre le C et le C++ au-delà de l'trucs de base et jusqu'à aujourd'hui, j'ai réalisé que les pointeurs sont passés par valeur à des fonctions, qui fait sens. Cela signifie que l'intérieur d'une fonction, je peux faire le copié pointer à une autre valeur, sans affecter l'original pointeur de l'appelant.

Quel est donc le point d'avoir une fonction d'en-tête qui dit:

void foo(int* const ptr);

À l'intérieur de cette fonction, vous ne pouvez pas faire ptr point à quelque chose d'autre parce que c'est const et vous ne voulez pas qu'elle soit modifiée, mais une fonction comme ceci:

void foo(int* ptr);

Fait le travail tout aussi bien! parce que le pointeur est copié de toute façon et le pointeur de l'appelant n'est pas affectée, même si vous modifiez la copie. Alors, quel est l'avantage de const?

201voto

tenfour Points 16759

const est un outil que vous devez utiliser dans la poursuite d'un important C++ concept:

Trouvez des bugs au moment de la compilation, plutôt qu'au moment de l'exécution, en obtenant le compilateur à appliquer ce que vous voulez dire.

Même si elle ne change pas la fonctionnalité, l'ajout d' const génère une erreur de compilation lorsque vous êtes en train de faire des choses que tu ne voulais pas faire. Imaginez la suite de la faute de frappe:

void foo(int* ptr)
{
    ptr = 0;// oops, I meant *ptr = 0
}

Si vous utilisez int* const, cela génère une erreur de compilation, car vous êtes la modification de la valeur ptr. L'ajout de restrictions via la syntaxe est une bonne chose en général. Il suffit de ne pas le prendre trop loin -- l'exemple que vous avez donné est un cas où la plupart des gens ne vous embêtez pas à l'aide de const.

75voto

Konrad Rudolph Points 231505

- Je faire un point de l'utilisation de seulement const arguments parce que cela permet plus de compilateur vérifie: si j'ai accidentellement ré-attribuer une valeur de l'argument dans la fonction, le compilateur me mord.

J'ai rarement réutiliser des variables, c'est plus propre de créer de nouvelles variables pour stocker de nouvelles valeurs, donc, essentiellement, toutes mes déclarations de variables sont const (sauf pour certains cas comme par exemple les variables de boucle où l' const permettrait d'éviter le code de travail).

Notez que cela n'a de sens qu'à la définition d'une fonction. Il n'appartient pas à la déclaration, qui est ce que l'utilisateur voit. Et l'utilisateur ne se soucie pas de savoir si j'utilise const pour les paramètres à l'intérieur de la fonction.

Exemple:

// foo.h
int frob(int x);
// foo.cpp
int frob(int const x) {
   MyConfigType const config = get_the_config();
   return x * config.scaling;
}

Remarquez à quel point l'argument et la variable locale sont const. Il n'est ni nécessaire , mais avec des fonctions qui sont même légèrement plus grande, ce a plusieurs reprises m'a permis de faire des erreurs.

20voto

Kerrek SB Points 194696

Votre question touche à quelque chose de plus général: fonctionnement d'arguments const?

Le constness de la valeur des arguments (comme le pointeur de la souris) est un détail d'implémentation, et il ne fait pas partie de la déclaration de la fonction. Cela signifie que votre fonction est toujours présent:

void foo(T);

Il est entièrement à la responsable de l'implémentation de la fonction si elle veut utiliser les fonctions-portée de l'argument variable dans un mutables ou de manière constante:

// implementation 1
void foo(T const x)
{
  // I won't touch x
  T y = x;
  // ...
}

// implementation 2
void foo(T x)
{
  // l33t coding skillz
  while (*x-- = zap()) { /* ... */ }
}

Si, de suivre la règle simple de ne jamais mettre const dans la déclaration (en-tête), et le mettre dans la définition (mise en œuvre) si vous ne voulez pas ou besoin de modifier la variable.

16voto

Le qualificateur const de niveau supérieur est ignoré dans les déclarations, donc les déclarations dans la question déclarent exactement la même fonction. En revanche, dans la définition (application) le compilateur vérifiera que si vous marquez le pointeur comme const, il n’est pas modifié dans le corps de la fonction.

14voto

Lundin Points 21616

Il y a beaucoup de choses à l' const mot-clé, il est plutôt complexe. En général, l'ajout d'un lot de const à votre programme est considéré comme une bonne pratique, la recherche sur le web pour "const correctness" et vous trouverez plein d'info à ce sujet.

Le mot-clé const est un soi-disant "type qualificatif", d'autres sont volatile et restrict. Au moins volatiles suit le même (confusion) règles de const.


Tout d'abord, le mot-clé const sert à deux fins. Le plus évident est de protéger les données (et les pointeurs) à partir intentionnelle ou accidentelle d'une mauvaise utilisation, en faisant d'eux en lecture seule. Toute tentative de modifier une variable const sera repéré par le compilateur au moment de la compilation.

Mais il y a aussi un autre but dans n'importe quel système avec mémoire en lecture seule, à savoir assurer une certaine variable est allouée à l'intérieur de ces la mémoire - c'est peut-être l'EEPROM ou flash par exemple. Ceux-ci sont connus en tant que non-volatile souvenirs, la mémoire non volatile. Une variable alloué dans la mémoire non volatile sera toujours, bien sûr, suivre toutes les règles d'une variable const.

Il y a différentes façons d'utiliser l' const mot-clé:

Déclarez une constante variable.

Cela peut être fait soit en tant que

const int X=1; or
int const X=1;

Ces deux formes sont tout à fait équivalents. Celle-ci est considérée comme un mauvais style et ne doit pas être utilisé.

La raison pour laquelle la deuxième ligne est considérée comme un mauvais style, est sans doute parce que "le stockage de classe prescripteurs" comme statique et externes peuvent également être déclarés après le type réel, int static etc. Mais le faire pour le stockage de classe prescripteurs est marqué comme obsolète par la fonction C (comité de l'ISO 9899 N1539 projet, 6.11.5). Par conséquent, par souci de cohérence, il ne faut pas écrire de type qualificatifs de cette manière. Il ne sert à rien d'autre but mais confondre le lecteur de toute façon.

Déclarer un pointeur vers une constante variable.

const int* ptr = &X;

Cela signifie que le contenu de 'X' ne peut pas être modifié. C'est la façon normale vous déclarer des pointeurs comme ce, principalement dans le cadre des paramètres de la fonction de "const correctness". Parce que " X " n'ont pas besoin d'être déclarée const, il pourrait être n'importe quelle variable. En d'autres termes, vous pouvez toujours "mise à niveau" une variable const. Techniquement, C permet également à un déclassement de la const à une simple variable explicite typecasts, mais le faire est considéré comme une mauvaise programmation et compilateurs généralement de donner des avertissements contre elle.

Déclarer un pointeur constant

int* const ptr = &X;

Cela signifie que le pointeur lui-même est constante. Vous pouvez modifier ce qu'il désigne, mais vous ne pouvez pas modifier le pointeur lui-même. Cela ne veut pas avoir de nombreuses utilisations, il y a quelques, de s'assurer qu'un pointeur à pointe-au (pointeur de pointeur) n'a pas changé d'adresse tout passé comme paramètre à une fonction. Vous aurez à écrire quelque chose de pas trop lisible comme ceci:

void func (int*const* ptrptr)

Je doute que beaucoup de programmeurs C peut obtenir la const et * le droit d'être là. Je sais que je ne peux pas, j'ai eu à le vérifier à l'aide de GCC. Je pense que c'est pourquoi il est rarement voir jamais que la syntaxe de pointeur de pointeur, même si elle est considérée comme une bonne pratique.

Constante des pointeurs peuvent aussi être utilisés pour s'assurer que le pointeur de la variable est déclarée dans la mémoire en lecture seule, par exemple, vous pourriez souhaiter pour déclarer une sorte de pointeur de base de la table de choix et de le répartir dans la mémoire non volatile.

Et bien sûr, comme indiqué par d'autres réponses, constante pointeurs peut également être utilisé pour appliquer des "const correctness".

Déclarer un pointeur constant constant de données

const int* const ptr=&X;

Ce sont les deux types de pointeur décrit ci-dessus combinés, avec tous les attributs de tous les deux.

Déclarer une lecture seule fonction membre (C++)

Puisque c'est marqué, C++, je dois aussi mentionner que vous pouvez déclarer les fonctions membres d'une classe comme const. Cela signifie que la fonction n'est pas autorisée à modifier à tout autre membre de la classe lorsqu'il est appelé, qui empêche le programmeur de la classe à partir des erreurs accidentelles, mais aussi d'informer l'appelant de la fonction de membre qu'ils ne seront pas gâcher quoi que ce soit jusqu'en l'appelant. La syntaxe est la suivante:

void MyClass::func (void) 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