El final constsignifica que la función Method3no modifica los miembros no mutables de su clase.
const int* constsignifica un puntero constante a un int constante: es decir, un puntero que no se puede cambiar, a un int que no se puede cambiar: la única diferencia entre esto y const int&es que se puedenull
const int* const&significa una referencia a un puntero constante a una constante int. Por lo general, los punteros no se pasan por referencia; const int* &tiene más sentido porque significaría que el puntero podría cambiarse durante la llamada al método, que sería la única razón por la que puedo ver pasar un puntero por referencia, const int* const&es a todos los efectos lo mismo const int* constexcepto que probablemente sea menos eficiente ya que los punteros son tipos de datos antiguos sin formato (POD) y, en general, deberían pasarse por valor.
# 5 dice que la declaración de función completa a la izquierda es const, lo que implica que esta es necesariamente una función miembro en lugar de una función libre.
# 4 dice que el puntero a la izquierda es const(no se puede cambiar para apuntar a una dirección diferente).
# 3 dice que el intde la izquierda es const(no se puede cambiar para tener un valor diferente).
# 2 dice que el puntero de la izquierda es const.
# 1 dice que el intde la izquierda es const.
Poniéndolo todo junto, puede leer esto como una constfunción miembro nombrada Method3que toma una referencia a un constpuntero a un int const(o a const int, si lo prefiere) y devuelve un constpuntero a un int const( const int).
const int* constes por tanto equivalente a int const * const.
Al leer expresiones con muchos consttokens y punteros, siempre intente leerlos de derecha a izquierda (después de aplicar la transformación anterior). Entonces, en este caso, el valor de retorno es un puntero constante a una constanteint . Hacer el puntero en sí constno tiene sentido aquí, ya que el valor de retorno no es un valor l que pueda modificarse. Sin constembargo, hacer el pointee garantiza que la persona que llama no puede modificar el int(o la matriz de ints) devuelto por Method3.
const int*const&se convierte en int const*const&, por lo que es una referencia a un puntero constante a una constanteint . Pasar un puntero constante por referencias masculinas tampoco tiene sentido: no puede modificar el valor referenciado ya que el puntero es consty las referencias y los punteros ocupan el mismo almacenamiento, por lo que tampoco hay ahorros de espacio.
El último constindica que el método no modifica el thisobjeto. El thispuntero dentro del cuerpo del método tendrá la declaración (teórica) T const * const this. Esto significa que un const T*objeto podrá llamar T::Method3().
Votar a favor de esto (y la respuesta similar de ildjarn), en parte por dejar claro que todo tiene más sentido si no pones las primeras consts al principio de la frase. Precisamente por eso creo que es una mala práctica poner constahí, aunque el lenguaje lo permita, y es el uso más común.
TED
12
Una forma fácil de recordar las reglas de constes pensar en ello de esta manera: se constaplica a la cosa a su izquierda, a menos que no haya nada a su izquierda.
Entonces, en el caso de const int * const, la primera constante no tiene nada a su izquierda, por lo que se aplica a inty la segunda tiene algo a su izquierda, por lo que se aplica al puntero.
Esta regla también le dice lo que sucedería en el caso en que lo haya hecho const int const *. Dado que ambas const se aplican a intesta expresión, es redundante y, por lo tanto, inválida.
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 */
Me gusta usar el método de "reloj" o "espiral" en el que a partir del nombre del identificador (en este caso Method3) se lee de izquierda a derecha, de izquierda a derecha, de atrás a izquierda, etc. para decodificar convenciones de nombres. Por tanto, const int* const Method3(const int* const&) constes un método de clase que no cambia ningún miembro de clase (de alguna clase sin nombre) y toma una referencia constante a un puntero que apunta a una constante inty devuelve un puntero constante a una constante int.
Una forma fácil de recordar la constante en C ++ es cuando ve un código en forma como:
XXX const;const YYY;
XXX, YYY será un componente constante, XXX constforma:
function ( def var )const;------#1*const;------#2
const YYY formar:
constint;------#3constdouble;
La gente suele utilizar estos tipos. Cuando vea en "const&"algún lugar, no se sienta confundido, const está describiendo algo antes de sí mismo. de modo que la respuesta a este problema es evidente ahora.
Solo quiero mencionar que de const int* const&hecho es una referencia constante a const int*. Por ejemplo:
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'
También es el caso de int* const&, Lo que significa: "Una referencia constante a int*".
Pero const int*&es una referencia no constante a const int*.
Espero que esto ayude.
const # 1: el puntero devuelto por Method3 se refiere a un int const.
const # 2: el valor del puntero devuelto por la función, en sí, es const. Esta es una constante inútil (aunque gramaticalmente válida), porque el valor de retorno de una función no puede ser un valor l.
const # 3: el tipo de puntero pasado por referencia a la función apunta a un const int.
const # 4: El valor del puntero pasado por referencia a la función es, en sí mismo, un puntero constante. Declarar un valor que se pasa a una función como constante normalmente no tendría sentido, pero este valor se pasa por referencia, por lo que puede ser significativo.
const # 5: La función (presumiblemente una función miembro) es constante, lo que significa que no está permitido (a) asignar nuevos valores a ningún miembro del objeto del que forma parte o (b) llamar a una función miembro no constante sobre el objeto o cualquiera de sus miembros.
const al final del método está el calificador que significa que el estado del objeto no se va a cambiar.
const int*const&significa recibir por referencia un puntero constante a una ubicación constante. No puede cambiar para apuntar a una ubicación diferente ni cambiar el valor al que apunta.
const int*const es el valor de retorno que también es un puntero constante a una ubicación constante.
Algunos ejemplos podrían ser buenos para demostrar este concepto, cuanto más mejor en mi humilde opinión.
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;}};
Respuestas:
Lea esto: https://isocpp.org/wiki/faq/const-correctness
El final
const
significa que la funciónMethod3
no modifica los miembros no mutables de su clase.const int* const
significa un puntero constante a un int constante: es decir, un puntero que no se puede cambiar, a un int que no se puede cambiar: la única diferencia entre esto yconst int&
es que se puedenull
const int* const&
significa una referencia a un puntero constante a una constante int. Por lo general, los punteros no se pasan por referencia;const int* &
tiene más sentido porque significaría que el puntero podría cambiarse durante la llamada al método, que sería la única razón por la que puedo ver pasar un puntero por referencia,const int* const&
es a todos los efectos lo mismoconst int* const
excepto que probablemente sea menos eficiente ya que los punteros son tipos de datos antiguos sin formato (POD) y, en general, deberían pasarse por valor.fuente
Es más fácil de entender si lo reescribe como completamente equivalente
luego léalo de derecha a izquierda.
# 5 dice que la declaración de función completa a la izquierda es
const
, lo que implica que esta es necesariamente una función miembro en lugar de una función libre.# 4 dice que el puntero a la izquierda es
const
(no se puede cambiar para apuntar a una dirección diferente).# 3 dice que el
int
de la izquierda esconst
(no se puede cambiar para tener un valor diferente).# 2 dice que el puntero de la izquierda es
const
.# 1 dice que el
int
de la izquierda esconst
.Poniéndolo todo junto, puede leer esto como una
const
función miembro nombradaMethod3
que toma una referencia a unconst
puntero a unint const
(o aconst int
, si lo prefiere) y devuelve unconst
puntero a unint const
(const int
).(La nota 2 es completamente superflua ).
fuente
En primer lugar
const T
es equivalente aT const
.const int* const
es por tanto equivalente aint const * const
.Al leer expresiones con muchos
const
tokens y punteros, siempre intente leerlos de derecha a izquierda (después de aplicar la transformación anterior). Entonces, en este caso, el valor de retorno es un puntero constante a una constanteint
. Hacer el puntero en síconst
no tiene sentido aquí, ya que el valor de retorno no es un valor l que pueda modificarse. Sinconst
embargo, hacer el pointee garantiza que la persona que llama no puede modificar elint
(o la matriz deint
s) devuelto porMethod3
.const int*const&
se convierte enint const*const&
, por lo que es una referencia a un puntero constante a una constanteint
. Pasar un puntero constante por referencias masculinas tampoco tiene sentido: no puede modificar el valor referenciado ya que el puntero esconst
y las referencias y los punteros ocupan el mismo almacenamiento, por lo que tampoco hay ahorros de espacio.El último
const
indica que el método no modifica elthis
objeto. Elthis
puntero dentro del cuerpo del método tendrá la declaración (teórica)T const * const this
. Esto significa que unconst T*
objeto podrá llamarT::Method3()
.fuente
const
s al principio de la frase. Precisamente por eso creo que es una mala práctica ponerconst
ahí, aunque el lenguaje lo permita, y es el uso más común.Una forma fácil de recordar las reglas de
const
es pensar en ello de esta manera: seconst
aplica a la cosa a su izquierda, a menos que no haya nada a su izquierda.Entonces, en el caso de
const int * const
, la primera constante no tiene nada a su izquierda, por lo que se aplica aint
y la segunda tiene algo a su izquierda, por lo que se aplica al puntero.Esta regla también le dice lo que sucedería en el caso en que lo haya hecho
const int const *
. Dado que ambas const se aplican aint
esta expresión, es redundante y, por lo tanto, inválida.fuente
fuente
Me gusta usar el método de "reloj" o "espiral" en el que a partir del nombre del identificador (en este caso
Method3
) se lee de izquierda a derecha, de izquierda a derecha, de atrás a izquierda, etc. para decodificar convenciones de nombres. Por tanto,const int* const Method3(const int* const&) const
es un método de clase que no cambia ningún miembro de clase (de alguna clase sin nombre) y toma una referencia constante a un puntero que apunta a una constanteint
y devuelve un puntero constante a una constanteint
.Espero que esto ayude,
Jason
fuente
Una forma fácil de recordar la constante en C ++ es cuando ve un código en forma como:
XXX, YYY será un componente constante,
XXX const
forma:const YYY
formar:La gente suele utilizar estos tipos. Cuando vea en
"const&"
algún lugar, no se sienta confundido, const está describiendo algo antes de sí mismo. de modo que la respuesta a este problema es evidente ahora.fuente
Solo quiero mencionar que de
const int* const&
hecho es una referencia constante aconst int*
. Por ejemplo:También es el caso de
int* const&
, Lo que significa: "Una referencia constante aint*
".Pero
const int*&
es una referencia no constante aconst int*
.Espero que esto ayude.
fuente
Leer de derecha a izquierda facilita la comprensión de los modificadores.
Un método const que toma una referencia a un puntero const a un int const llamado
Method3
que devuelve un puntero const a un int const.mutable
)fuente
const # 1: el puntero devuelto por Method3 se refiere a un int const.
const # 2: el valor del puntero devuelto por la función, en sí, es const. Esta es una constante inútil (aunque gramaticalmente válida), porque el valor de retorno de una función no puede ser un valor l.
const # 3: el tipo de puntero pasado por referencia a la función apunta a un const int.
const # 4: El valor del puntero pasado por referencia a la función es, en sí mismo, un puntero constante. Declarar un valor que se pasa a una función como constante normalmente no tendría sentido, pero este valor se pasa por referencia, por lo que puede ser significativo.
const # 5: La función (presumiblemente una función miembro) es constante, lo que significa que no está permitido (a) asignar nuevos valores a ningún miembro del objeto del que forma parte o (b) llamar a una función miembro no constante sobre el objeto o cualquiera de sus miembros.
fuente
const
al final del método está el calificador que significa que el estado del objeto no se va a cambiar.const int*const&
significa recibir por referencia un puntero constante a una ubicación constante. No puede cambiar para apuntar a una ubicación diferente ni cambiar el valor al que apunta.const int*const
es el valor de retorno que también es un puntero constante a una ubicación constante.fuente
Algunos ejemplos podrían ser buenos para demostrar este concepto, cuanto más mejor en mi humilde opinión.
¡Espero que esto ayude!
fuente