Le final constsignifie que la fonction Method3ne modifie pas les membres non mutables de sa classe.
const int* constsignifie un pointeur constant vers une constante int: c'est-à-dire un pointeur non modifiable, vers un int non modifiable: la seule différence entre this et const int&est qu'il peut êtrenull
const int* const&signifie une référence à un pointeur constant vers une constante int. En général, les pointeurs ne sont pas passés par référence; const int* &a plus de sens car cela signifierait que le pointeur pourrait être changé pendant l'appel de méthode, ce qui serait la seule raison pour laquelle je peux voir pour passer un pointeur par référence, const int* const&est à toutes fins utiles le même que const int* constsauf qu'il est probablement moins efficace car les pointeurs sont des types de données anciennes (POD) et ceux-ci devraient, en général, être passés par valeur.
# 5 dit que la déclaration de fonction entière à gauche est const, ce qui implique qu'il s'agit nécessairement d'une fonction membre plutôt que d'une fonction libre.
# 4 indique que le pointeur à gauche est const(ne peut pas être changé pour pointer vers une adresse différente).
# 3 indique que le intà gauche est const(ne peut pas être changé pour avoir une valeur différente).
# 2 indique que le pointeur à gauche est const.
# 1 dit que le intvers la gauche est const.
En mettant tout cela ensemble, vous pouvez lire ceci comme une constfonction membre nommée Method3qui prend une référence à un constpointeur vers un int const(ou a const int, si vous préférez) et renvoie un constpointeur vers un int const( const int).
const int* constéquivaut donc à int const * const.
Lorsque vous lisez des expressions contenant de nombreux constjetons et pointeurs, essayez toujours de les lire de droite à gauche (après avoir appliqué la transformation ci-dessus). Donc, dans ce cas, la valeur de retour est un pointeur const vers un constint . Faire le pointeur lui-même constn'a aucun sens ici car la valeur de retour n'est pas une lvalue qui pourrait être modifiée. Faire le pointe const, cependant, garantit que l'appelant ne peut pas modifier le int(ou le tableau de ints) renvoyé par Method3.
const int*const&devient int const*const&, donc c'est une référence à un pointeur const vers un constint . Passer un pointeur const par des références mâles n'a aucun sens non plus - vous ne pouvez pas modifier la valeur référencée car le pointeur est constet les références et les pointeurs occupent un stockage égal, donc il n'y a pas non plus d'économie d'espace.
Le dernier constindique que la méthode ne modifie pas l' thisobjet. Le thispointeur dans le corps de la méthode aura la déclaration (théorique) T const * const this. Cela signifie qu'un const T*objet pourra appeler T::Method3().
Voter pour cela (et la réponse similaire d'ildjarn), en partie pour faire valoir que tout cela a plus de sens si vous ne mettez pas les premiers consts en tête de la phrase. C'est précisément pourquoi je pense que c'est une mauvaise pratique d' consty mettre , même si la langue le permet, et c'est l'usage le plus courant.
TED
12
Un moyen facile de se souvenir des règles de constest de le penser de cette façon: consts'applique à la chose à sa gauche, à moins qu'il n'y ait rien à sa gauche.
Donc, dans le cas de const int * const, le premier const n'a rien à sa gauche, donc il s'applique à intet le second a quelque chose à sa gauche, donc il s'applique au pointeur.
Cette règle vous indique également ce qui se passerait dans le cas où vous en avez const int const *. Étant donné que les deux const s'appliquent à intcette expression, elle est redondante et donc invalide.
const/* don't modify the int or array of ints' value(s) */int*const/* as a retval, ignored. useless declaration */Method3(const/* don't modify the int or array of ints' value(s) */int*const/* don't modify the pointer's value, the address to which `pointer` points to. e.g. you cannot say `++pointer` */&)const;/* this method does not modify the instance/object which implements the method */
J'aime utiliser la méthode "horloge" ou "spirale" où, à partir du nom de l'identifiant (dans ce cas Method3), vous lisez d'avant en arrière de gauche à droite, d'arrière à gauche, etc. afin de décoder conventions de nommage. Il en const int* const Method3(const int* const&) constva de même pour une méthode de classe qui ne change aucun membre de classe (d'une classe sans nom) et prend une référence constante à un pointeur qui pointe vers une constante intet retourne un pointeur de constante vers une constante int.
Un moyen simple de se souvenir du const en C ++ est de voir du code sous une forme comme:
XXX const;const YYY;
XXX, YYY sera un composant constant, de la XXX constforme:
function ( def var )const;------#1*const;------#2
const YYY forme:
constint;------#3constdouble;
Les gens utilisent généralement ces types. Quand vous voyez "const&"quelque part, ne vous sentez pas confus, const décrit quelque chose avant lui-même. la réponse à ce problème est donc évidente maintenant.
Je veux seulement mentionner que const int* const&c'est effectivement une référence constante à const int*. Par exemple:
int i =0;int j =1;int* p =&i;int* q =&j;constint*const& cpref = p;
cpref = q;//Error: assignment of read-only reference 'cpref'
C'est aussi le cas pour int* const&, ce qui signifie: "Une référence constante à int*".
Mais const int*&est une référence non constante à const int*.
J'espère que cela t'aides.
const # 1: Le pointeur retourné par Method3 fait référence à un const int.
const # 2: La valeur du pointeur renvoyée par la fonction, elle-même, est const. C'est un const inutile (bien que grammaticalement valide), car la valeur de retour d'une fonction ne peut pas être une valeur l.
const # 3: Le type de pointeur passé par référence à la fonction pointe vers un const int.
const # 4: La valeur du pointeur passée par référence à la fonction est elle-même un pointeur const. Déclarer une valeur qui est passée à une fonction comme const serait normalement inutile, mais cette valeur est passée par référence, donc elle peut être significative.
const # 5: La fonction (vraisemblablement une fonction membre) est const, ce qui signifie qu'elle n'est pas autorisée à (a) attribuer de nouvelles valeurs à des membres de l'objet dont elle fait partie ou (b) appeler une fonction membre non-const sur l'objet ou sur l'un de ses membres.
const à la fin de la méthode se trouve le qualificatif signifiant que l'état de l'objet ne va pas être changé.
const int*const&signifie recevoir par référence un pointeur const vers un emplacement const. Il ne peut ni changer pour pointer vers un emplacement différent ni changer la valeur vers laquelle il pointe.
const int*const est la valeur de retour qui est également un pointeur constant vers un emplacement constant.
Quelques exemples pourraient être intéressants pour illustrer ce concept, plus il y en a, mieux c'est.
classTestClass{private:int iValue;int* oValuePtr;int& oValueRef;public:intTestClass::ByValMethod1(intValue){// Value can be modifiedValue++;// iValue can be modified
iValue =Value;
iValue +=1;// Return value can be modifiedreturn++iValue;}intTestClass::ByValMethod2(constintValue){// Value *cannot* be modified// Variable is const variableValue++;// iValue can be modified
iValue =Value;
iValue +=1;// Return value can be modifiedreturn++iValue;}constintTestClass::ByValMethod3(intValue){// Value can be modifiedValue++;// iValue can be modified
iValue =Value;
iValue +=1;// Return value can be modifiedreturn++iValue;}constintTestClass::ByValMethod4(constintValue){// Value *cannot* be modified// Variable is const variableValue++;// iValue can be modified
iValue =Value;
iValue +=1;// Return value can be modifiedreturn++iValue;}constintTestClass::ByValMethod5(constintValue)const{// Value *cannot* be modified// Variable is const variableValue++;// iValue *cannot* be modified// Access through a const object
iValue =Value;
iValue +=1;// Return value *cannot* be modified// Access through a const objectreturn++iValue;}int&TestClass::ByRefMethod1(int&Value){// Value can be modifiedValue++;// oValueRef can be modified
oValueRef =Value;
oValueRef +=1;// Return value can be modifiedreturn++oValueRef;}int&TestClass::ByRefMethod2(constint&Value){// Value *cannot* be modified// Variable is const variableValue++;// oValueRef can be modified
oValueRef =Value;
oValueRef +=1;// Return value can be modifiedreturn++oValueRef;}constint&TestClass::ByRefMethod3(int&Value){// Value can be modifiedValue++;// oValueRef can be modified
oValueRef =Value;
oValueRef +=1;// Return value can be modifiedreturn++oValueRef;}constint&TestClass::ByRefMethod4(constint&Value){// Value *cannot* be modified// Variable is const variableValue++;// oValueRef can be modified
oValueRef =Value;
oValueRef +=1;// Return value can be modifiedreturn++oValueRef;}constint&TestClass::ByRefMethod5(constint&Value)const{// Value *cannot* be modified// Variable is const variableValue++;// oValueRef can be modified
oValueRef =Value;
oValueRef +=1;// Return value can be modifiedreturn++oValueRef;}int*TestClass::PointerMethod1(int*Value){// Value can be modifiedValue++;// oValuePtr can be assigned
oValuePtr =Value;// oValuePtr can be modified
oValuePtr +=1;// Return value can be modifiedreturn++oValuePtr;}int*TestClass::PointerMethod2(constint*Value){// Value can be modifiedValue++;// oValuePtr cannot be assigned// const int* to int*
oValuePtr =Value;// oValuePtr can be modified
oValuePtr +=1;// Return value can be modifiedreturn++oValuePtr;}constint*TestClass::PointerMethod3(int*Value){// Value can be modifiedValue++;// oValuePtr can be assigned
oValuePtr =Value;// iValue can be modified
oValuePtr +=1;// Return value can be modifiedreturn++oValuePtr;}constint*TestClass::PointerMethod4(constint*Value){// Value cannot be modifiedValue++;// oValuePtr *cannot* be assigned// const int* to int*
oValuePtr =Value;// oValuePtr can be modified
oValuePtr +=1;// Return value can be modifiedreturn++oValuePtr;}constint*TestClass::PointerMethod5(constint*Value)const{// Value can be modified++Value;// oValuePtr *cannot* be assigned// const int* to int* const// Access through a const object
oValuePtr =Value;// oValuePtr *cannot* be modified// Access through a const object
oValuePtr +=1;// Return value *cannot* be modifiedreturn++oValuePtr;}};
Réponses:
Lisez ceci: https://isocpp.org/wiki/faq/const-correctness
Le final
const
signifie que la fonctionMethod3
ne modifie pas les membres non mutables de sa classe.const int* const
signifie un pointeur constant vers une constante int: c'est-à-dire un pointeur non modifiable, vers un int non modifiable: la seule différence entre this etconst int&
est qu'il peut êtrenull
const int* const&
signifie une référence à un pointeur constant vers une constante int. En général, les pointeurs ne sont pas passés par référence;const int* &
a plus de sens car cela signifierait que le pointeur pourrait être changé pendant l'appel de méthode, ce qui serait la seule raison pour laquelle je peux voir pour passer un pointeur par référence,const int* const&
est à toutes fins utiles le même queconst int* const
sauf qu'il est probablement moins efficace car les pointeurs sont des types de données anciennes (POD) et ceux-ci devraient, en général, être passés par valeur.la source
C'est plus facile à comprendre si vous réécrivez cela comme l'équivalent complètement
puis lisez-le de droite à gauche.
# 5 dit que la déclaration de fonction entière à gauche est
const
, ce qui implique qu'il s'agit nécessairement d'une fonction membre plutôt que d'une fonction libre.# 4 indique que le pointeur à gauche est
const
(ne peut pas être changé pour pointer vers une adresse différente).# 3 indique que le
int
à gauche estconst
(ne peut pas être changé pour avoir une valeur différente).# 2 indique que le pointeur à gauche est
const
.# 1 dit que le
int
vers la gauche estconst
.En mettant tout cela ensemble, vous pouvez lire ceci comme une
const
fonction membre nomméeMethod3
qui prend une référence à unconst
pointeur vers unint const
(ou aconst int
, si vous préférez) et renvoie unconst
pointeur vers unint const
(const int
).(Le n ° 2 est entièrement superflu .)
la source
Tout d'abord
const T
équivaut àT const
.const int* const
équivaut donc àint const * const
.Lorsque vous lisez des expressions contenant de nombreux
const
jetons et pointeurs, essayez toujours de les lire de droite à gauche (après avoir appliqué la transformation ci-dessus). Donc, dans ce cas, la valeur de retour est un pointeur const vers un constint
. Faire le pointeur lui-mêmeconst
n'a aucun sens ici car la valeur de retour n'est pas une lvalue qui pourrait être modifiée. Faire le pointeconst
, cependant, garantit que l'appelant ne peut pas modifier leint
(ou le tableau deint
s) renvoyé parMethod3
.const int*const&
devientint const*const&
, donc c'est une référence à un pointeur const vers un constint
. Passer un pointeur const par des références mâles n'a aucun sens non plus - vous ne pouvez pas modifier la valeur référencée car le pointeur estconst
et les références et les pointeurs occupent un stockage égal, donc il n'y a pas non plus d'économie d'espace.Le dernier
const
indique que la méthode ne modifie pas l'this
objet. Lethis
pointeur dans le corps de la méthode aura la déclaration (théorique)T const * const this
. Cela signifie qu'unconst T*
objet pourra appelerT::Method3()
.la source
const
s en tête de la phrase. C'est précisément pourquoi je pense que c'est une mauvaise pratique d'const
y mettre , même si la langue le permet, et c'est l'usage le plus courant.Un moyen facile de se souvenir des règles de
const
est de le penser de cette façon:const
s'applique à la chose à sa gauche, à moins qu'il n'y ait rien à sa gauche.Donc, dans le cas de
const int * const
, le premier const n'a rien à sa gauche, donc il s'applique àint
et le second a quelque chose à sa gauche, donc il s'applique au pointeur.Cette règle vous indique également ce qui se passerait dans le cas où vous en avez
const int const *
. Étant donné que les deux const s'appliquent àint
cette expression, elle est redondante et donc invalide.la source
la source
J'aime utiliser la méthode "horloge" ou "spirale" où, à partir du nom de l'identifiant (dans ce cas
Method3
), vous lisez d'avant en arrière de gauche à droite, d'arrière à gauche, etc. afin de décoder conventions de nommage. Il enconst int* const Method3(const int* const&) const
va de même pour une méthode de classe qui ne change aucun membre de classe (d'une classe sans nom) et prend une référence constante à un pointeur qui pointe vers une constanteint
et retourne un pointeur de constante vers une constanteint
.J'espère que cela t'aides,
Jason
la source
Un moyen simple de se souvenir du const en C ++ est de voir du code sous une forme comme:
XXX, YYY sera un composant constant, de la
XXX const
forme:const YYY
forme:Les gens utilisent généralement ces types. Quand vous voyez
"const&"
quelque part, ne vous sentez pas confus, const décrit quelque chose avant lui-même. la réponse à ce problème est donc évidente maintenant.la source
Je veux seulement mentionner que
const int* const&
c'est effectivement une référence constante àconst int*
. Par exemple:C'est aussi le cas pour
int* const&
, ce qui signifie: "Une référence constante àint*
".Mais
const int*&
est une référence non constante àconst int*
.J'espère que cela t'aides.
la source
La lecture de droite à gauche facilite la compréhension des modificateurs.
Une méthode const qui prend une référence à un pointeur const vers un const int appelé
Method3
qui retourne un pointeur const vers un const int.mutable
)la source
const # 1: Le pointeur retourné par Method3 fait référence à un const int.
const # 2: La valeur du pointeur renvoyée par la fonction, elle-même, est const. C'est un const inutile (bien que grammaticalement valide), car la valeur de retour d'une fonction ne peut pas être une valeur l.
const # 3: Le type de pointeur passé par référence à la fonction pointe vers un const int.
const # 4: La valeur du pointeur passée par référence à la fonction est elle-même un pointeur const. Déclarer une valeur qui est passée à une fonction comme const serait normalement inutile, mais cette valeur est passée par référence, donc elle peut être significative.
const # 5: La fonction (vraisemblablement une fonction membre) est const, ce qui signifie qu'elle n'est pas autorisée à (a) attribuer de nouvelles valeurs à des membres de l'objet dont elle fait partie ou (b) appeler une fonction membre non-const sur l'objet ou sur l'un de ses membres.
la source
const
à la fin de la méthode se trouve le qualificatif signifiant que l'état de l'objet ne va pas être changé.const int*const&
signifie recevoir par référence un pointeur const vers un emplacement const. Il ne peut ni changer pour pointer vers un emplacement différent ni changer la valeur vers laquelle il pointe.const int*const
est la valeur de retour qui est également un pointeur constant vers un emplacement constant.la source
Quelques exemples pourraient être intéressants pour illustrer ce concept, plus il y en a, mieux c'est.
J'espère que ça aide!
la source