29 votes

Pourquoi l'élément déréférencé dans le vecteur const des pointeurs int est-il mutable?

Je ne suis pas sûr que le vrai sens de l' const vector<int *> donc j'ai compilé le code ci-dessous pour vous faire une idée, mais je suis maintenant plus confus.

vector<int *> v;
int x = 1, y = 2;
v.push_back(&x);
v.push_back(&y);

const vector<int *> w = v;
w[0] = &y;   //failed. Element is a constant pointer?
*(w[0]) ++;  //failed. Element pointer references to constant value?

Si je m'étais arrêté là, j'aurais cru qu' const vector<int *> est un vecteur d' const int * const, mais ensuite j'ai essayé le suivant qui a clairement contredit cette hypothèse.

*(w[0]) += 3; //passed. Value not constant?
*(w[0]) = 20; //passed. Why...

Maintenant, *(w[0]) , pour une raison inconnue de moi, évidemment, des friandises ++ et += et l'affectation différemment. Je me suis convaincu que const vector seulement déclare un objet constant de l' vector de la classe et que les résultats ci-dessus peut dépendre de la mise en œuvre effective de la surcharge d'opérateur de vector classe. Mais je ne peut pas envelopper la tête autour de cela. Quelqu'un peut-il aider à expliquer, s'il vous plaît?

Si elle est pertinente, j'ai utilisé g++ 4.2 sur un Mac.

33voto

songyuanyao Points 2265

Pourquoi est déréférencé élément const vecteur de pointeurs int muable?

Pour const vector<int *>, l'élément sera const pointeur de non-const, c'est à dire int * const, de sorte que vous pouvez modifier l'objet pointé par le pointeur, mais pas le pointeur lui-même.

En fonction de la Priorité de l'Opérateur, postfix opérateur d'incrémentation a une priorité plus élevée que operator*, alors *(w[0]) ++; est équivalent à

* ((w[0]) ++);

L'incrémentation du pointeur est effectuée au début, puis il échoue. w[0] = &y; est également essayer de modifier le pointeur, donc il échoue aussi.

D'autre part, (*w[0]) ++; (c'est à dire un incrément sur la pointee) ce serait bien. Et les affirmations suivantes sont bien aussi, parce qu'ils sont à la fois modifiant les objets pointée par le pointeur, pas les pointeurs.

*(w[0]) += 3; //passed.
*(w[0]) = 20; //passed.

9voto

Joachim Pileborg Points 121221

C'est une question de priorité de l' opérateur .

Lorsque vous effectuez *(w[0]) ++ vous essayez de modifier le pointeur .

Lorsque vous effectuez *(w[0]) += 3 vous modifiez les données pointées par le pointeur.

6voto

El Profesor Points 10915

w est const vector<int *>. L' const qualificatif est appliquée au vecteur. Par conséquent, la correspondante const fonction de membre sera utilisé pour l' operator[]:

const_reference operator[]( size_type pos ) const;

Puisque le vecteur est - const-qualifiés et contient des éléments de type int * ( et pas const int *), le type de l'expression w[0] est int * const& (au lieu de const int *&). C'est, il est une référence à un pointeur constant vers un int , et non une référence à un pointeur vers une constante int: la constness est appliqué à la le pointeur lui-même, de ne pas les données se faire remarquer.

En faisant *(w[0]) += 3 vous n'êtes pas modifier la valeur du pointeur, le vecteur des rendements (qui est - const), mais la valeur de ce pointeur pointe vers. Depuis ce pointeur est de type int * const (et pas const int *), vous pouvez modifier ce qu'il désigne, de sorte qu'il fonctionne. Toutefois, w[0] = &y est de l'exécution d'une affectation sur un pointeur constant, de sorte qu'il ne compile pas.

1voto

n.caillou Points 696

const vector<T> vous permet d'accéder à ses éléments comme T const & (c'est à dire const T &). Dans ce cas, T est int *, c'est donc int * const &, const référence à un pointeur qui pointe vers une int. Le pointeur est constant, mais le type int n'est pas.

Le type du vecteur aurait fallu vector<int const *> (c'est à dire vector<const int*>) auquel cas les éléments seraient accessibles via int const * const &.

Ligne de fond, constness est transitive avec des modèles, mais pas avec des pointeurs. Et si vous mettez des pointeurs dans les modèles, vous obtenez un peu des deux comportements.

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