#include using namespace std; int main(int argc, char* argv[]) { int i1 = 0; int i2 = 10; const int *p = &i1; int const *p2 = &i1; const int const *p3 = &i1; p = &i2; p2 = &i2; p3 = &i2; cout << *p << endl << *p2 <<endl << *p3 <<endl; return 0; }
Le code peut être compilé avec VC6.0 et VC2010. Mais j’ai des questions comme coup:
const int * p = & i1;
Cela signifie que les points “p” ne peuvent pas être modifiés, mais que p ne peut pas être modifié, n’est-ce pas? alors
p = & i2;
- Impossible d’utiliser .begin () ou .end () sur un tableau
- Une ligne pour RAII sur non pointeur?
- Prolonger la vie des threads avec la synchronisation (C ++ 11)
- Pourquoi ne pouvons-nous pas initialiser les membres de la classe lors de leur déclaration?
- Spécialisation partielle des modèles basée sur la «signature» de type entier?
cette ligne peut être respectée, oui?
Cette ligne:
int const *p2 = &i1;
Dans mon esprit, cela signifie que p2 ne peut pas être modifié alors que quels points p2 peuvent être modifiés, ai-je raison? Pourquoi le
p2 = & i2;
peut être compilé?
A propos de cette ligne:
const int const * p3 = & i1;
p3 = & i2;
Oh, mon dieu … je suis fou. Je n’ai aucune idée pourquoi cette ligne peut être compilée sans erreur … Tout organisme peut-il m’aider?
Un autre code qui m’a confondu est ici:
class Coo2 { public: Coo2() : p(new int(0)) {} ~Coo2() {delete p;} int const * getP() const { *p = 1; return this->p; } private: int* p; };
pourquoi ce code peut être compilé? Dans
int const * getP () const
J’ai changer la valeur ou * p!
Avec l’aide du pointeur, vous pouvez réellement faire deux choses.
Maintenant, quand vous dites, int const * ptr ou int const * ptr, il entre dans la première catégorie. C’est pareil que –
const int num = 5; // Both mean the same. int const num = 5;
Pour que vous ne puissiez pas réellement changer d’emplacement, c’est-à-dire que vous pointiez sur un emplacement constant mais que vous puissiez modifier les données, la sémantique devrait être int* const
. Puisque le contenu du pointeur est une constante, il devrait être initialisé pendant la déclaration.
int num = 5; int* const ptr; // Wrong ptr = # // Wrong int* const ptr = # *ptr = 100;
Cependant, il existe un troisième type. Pointeur constant sur un emplacement constant, qui ne peut ni pointer vers un autre emplacement de mémoire ni modifier les données pointées. (c’est-à-dire, const int * const)
Et maintenant, pour répondre aux questions , les deux premières peuvent être compilées car elles ne désignent pas des emplacements constants. Ils peuvent donc être modifiés ultérieurement.
const int const *p3 = &i1; p3 = &i2; // Wrong
Dans l’extrait de p3
ci-dessus, p3
est un pointeur constant sur un emplacement constant. Donc, il ne peut pas être modifié.
const
à la fin d’une fonction membre dit qu’il ne va pas changer l’état de l’object. Quand vous dites *p = 1;
, vous ne modifiez pas l’état de l’object. p
pointe toujours sur le même emplacement mémoire. Ce n’est pas autorisé à faire –
int const * Coo2::getP() const { *p = 1; // State of `p` is still not modified. p = new int ; // Error: Changing the memory location to which p points. // This is what changing the state of object mean and // is not allowed because of `const` keyword at the end of function return this->p; }
J’espère que maintenant vous comprenez pourquoi le programme comstack 🙂
Nous considérons ici 4 types de déclarations de pointeurs:
int * w;
Cela signifie que w est un pointeur sur une valeur de type entier. Nous pouvons modifier le pointeur et son contenu. Si nous initialisons la déclaration w tant que ci-dessous: int * w = &a;
Ensuite, les deux opérations ci-dessous sont viables:
w = &b;
(vrai)
*w = 1;
(vrai)
int * const x;
Cela signifie que x est un pointeur constant qui pointe vers une valeur de type entier. Si nous initialisons la déclaration x while comme ci-dessous:
int * const x = &a;
Ensuite, nous ne pouvons pas faire: x = &b;(wrong)
car x est un pointeur constant et ne peut pas être modifié.
Cependant, il est possible de faire: *x = 1;(true)
, car le contenu de x n’est pas constant.
int const * y;
// les deux signifient la même chose
const int * y;
Cela signifie que y est un pointeur qui pointe vers une valeur entière constante. Si nous initialisons la déclaration y while comme ci-dessous:
int const * y = &a;
Ensuite, il est possible de faire: y=&b;(true)
car y est un pointeur non constant pouvant pointer n’importe où.
Cependant, nous ne pouvons pas faire: *y=1;(wrong)
car la variable pointée vers y est une variable constante et ne peut pas être modifiée.
int const * const z;
// les deux signifient la même chose
const int * const z;
Cela signifie que z est un pointeur constant qui pointe vers une valeur entière constante. Si nous initialisons z en tant que déclaration comme ci-dessous:
int const * const z = &a;
Par conséquent, les opérations non en aval sont viables:
z = &b;(wrong)
*z = 1;(wrong)
int const * p;
et const int * p
sont les mêmes. C’est lorsque le const
vient après le *
que la sémantique de l’expression change.
Je sais, c’est fou.
const int *p = &i1; int const *p2 = &i1;
Ces deux déclarent des pointeurs non const à des données const.
C’est-à-dire qu’en utilisant p
, vous ne pouvez pas modifier les données sur lesquelles il pointe. Toutefois, vous pouvez modifier le pointeur lui-même, par exemple, en atsortingbuant à p = &i2
légale. Mais *p = 87987
est illégal, car les données *p = 87987
par p
sont const!
–
int * const p = &i1;
Ceci déclare le pointeur const sur des données non constantes. Autrement dit, p=&i2
est illégal, mais *p = 98789
est légal.
–
const int * const p = &i1;
Ceci déclare le pointeur const aux données const. C’est-à-dire que p=&i2
et *p=87897
sont *p=87897
illégaux.
Les deux sont exactement les mêmes. Ce qui compte, c’est la position du qualificatif par rapport à l’astérisque ( *
):
int const *p; // normal pointer to const int const int *p; // ditto int *const p; // const pointer to normal int (rarely useful) int const * const p; // const pointer to const int
Non, le mot-clé const
précédant le * signifie que la variable à laquelle vous faites référence est une variable “const” et qu’elle ne peut pas être modifiée.
Foo* const p = &bar;
const Foo* const p = &bar
Il est parfaitement correct d’avoir un pointeur de const int* foo
assigné à un pointeur de const int* const bar
tout comme il est bien d’avoir la valeur d’un const int
assignée à un const int
. Pensez-y de la même manière.
int const * est identique à const int *
Succinctement; chaque combinaison de lecture / écriture int & pointer;
int main() { int a,b; int* w; // read/write int, read/write pointer w= &b; // good *w= 1; // good int* const x = &a; // read only pointer, read/write int // x = &b; // compilation error *x = 0; // good int const * y; // read/write ptr, read only int const int * y2; // " " " y = &a; // good // *y = 0; // compilation error y2 = &a; // good // *y2 = 0; // compilation error int const * const z = &a; // read only ptr and read only int const int * const z2 = &b; // " " " " // *z = 0; // compilation error // z = &a; // compilation error // *z2 = 0; // compilation error // z2 = &a; // compilation error }