2009-12-02 22 views
6

Etiquetado como tarea porque esta era una pregunta a mitad de período que escribí y no entiendo la respuesta. Se me pidió que explique el propósito de cada const en la siguiente declaración:Corrección de const: const char const * const GetName const (// stuff);

const char const * const GetName() const { return m_name; }; 

Así que, ¿cuál es la explicación de cada uno de estos consts?

+3

El código probablemente sea diferente, ya que lo que ha publicado es incorrecto. Probablemente fue algo en la línea de 'clase X {const char * const getName() const {return m_name; } ... ' –

+0

Espera, ¿escribiste la mitad del período? – tster

+2

La doble const en 'const char const' es válida en C99, pero no es válida en C++. Solo una const permitida, pero cuál eliminar no importa. –

Respuesta

6

Tómelos desde la derecha. El anterior al ; le dice al cliente que este es un nivel de diseño constante, es decir, no altera el estado del objeto. (Piense en esto como un método de sólo lectura.)

bien, ahora el valor de retorno:

const char const *const 

Este es un puntero constante a bien ... aquí vamos boom! Tiene un const extra: un error de sintaxis. Los siguientes son equivalentes: const T o T const. Si saca un const, obtiene un puntero constante a caracteres constantes. ¿Eso ayuda?

+0

Para aclarar, la T en su ejemplo es la char, no la char *. Poniéndolo juntos: const char * const es equivalente a char const * const. – Marcin

+0

¿Esto no funcionaría? Mi prof es un hombre furtivo, al parecer .. –

+0

puntero constante a una constante characeterS o personaje? –

2

Tiene una configuración más de la que se permite sintácticamente, ese código no se compilaría. Retire el "const" después de "char" y antes del "*". Además, el último const debe venir antes del cuerpo de la función. Ayuda leer cosas como esta de derecha a izquierda.

const char * const GetName() const { return m_name; }; 

tienes una función const (es decir, la función no altera el estado de la clase.), Que devuelve un puntero constante a un const char.

+0

El último const también debe moverse antes del cuerpo del método, y para ser precisos, no puede ser una función, sino un método. –

+0

@dribeas, esa es una función. Los métodos no existen en C++. –

+0

Sí, tiene razón sobre el cuerpo, pero no sobre el método frente a la declaración de la función. –

0

última const:

  • función no cambia las partes íntimas de la clase

una después de la última const:

  • Es un puntero constante (es decir, el lugar se puntos a es constante)

segundo const:

  • La función devuelve un const char (es decir, el contenido del carbón es constante)

Primero:

  • Ni idea?

Así que para ser completa: La función devuelve un puntero constante (siempre misma ubicación) a un char constante (siempre mismo contenido) y la función no modifica el estado de la clase.

+0

Un método const no puede cambiar CUALQUIER miembro de la clase ni llamar a ningún método que no sea const. – quamrana

+0

@quamrana: un método const puede cambiar los miembros de datos que son estáticos o mutables. –

+0

@Jerry: Tienes razón. Permítanme reformular: un método const no puede cambiar ningún miembro público, protegido o privado a menos que sean estáticos o mutables. – quamrana

0

const (1) char const (2) * const GetName() {return m_name; } const (3);

const char * const result = aaa.GetNAme();

3 - método const, no se permite cambiar miembros ni llamar a ningún método no const.

1 - no permite modificar el interior del puntero, es decir * resultado = ..

2 - no permite mover el puntero, es decir, resultado = NULL

2

(1) const char (2) const * (3) const GetName() {return m_name; } (4) const;

  1. El contenido de la matriz de caracteres es const. Esto es bueno cuando devuelve el puntero del miembro objeto. Dado que le da un puntero a su miembro para terceros, desea evitar que se modifique desde el exterior.
  2. Este formulario no se utiliza con frecuencia y esencialmente igual que (1)
  3. Nuestro puntero a la matriz char es const, por lo que no puede cambiar dónde señala el puntero también.
  4. califica el GetName() en sí mismo, lo que significa que el método no cambia la clase que se aplica también. Por lo tanto, solo se puede invocar para el objeto const de este tipo. Este formulario normalmente se usa como GetName (...) const.

Como ya se ha mencionado en otra respuesta que el truco para "recordar" que se lee de derecha a izquierda:

  • const T * - puntero a const T
  • T * const - puntero constante a T
+1

Incorrecto: (1) y (2) son equivalentes. Es decir, 'const T' y' T const' son lo mismo. Por otro lado, 'T const *' y 'T * const' son diferentes, uno marca el T como constante, el otro marca el puntero como constante. –

+0

Upps, tienes razón, corrigió – dimba

1

Editar: Parece que pegué el código incorrectamente en Comeau, o que fue editado en la respuesta original para ser correcto. En cualquier caso, estoy conservando la respuesta a continuación como si el código fuera incorrecto.

Comeau compilador de línea da los siguientes resultados:

"ComeauTest.c", line 4: error: type qualifier specified more than once
const char const * const GetName() { return m_name; } const; ^

"ComeauTest.c", line 4: warning: type qualifier on return type is meaningless const char const * const GetName() { return m_name; } const; ^

"ComeauTest.c", line 4: error: declaration does not declare anything const char const * const GetName() { return m_name; } const;

Lo que esto significa es que su declaración está mal formado.

const char const * const GetName() { return m_name; } const; 

La primera y la segunda conste significan lo mismo. No puede especificar el mismo calificador más de una vez, por lo que uno de estos debería eliminarse para que el código se compile. Ambas consts especifican que los valores apuntada por el puntero devuelto por GetName no puede ser modificado, por lo que un código como éste no válido:

const char* name = c.GetName(); 
name[0] = 'a'; 

La tercera const especifica que el puntero devuelto por GetName() en sí no puede ser modificado, pero como Comeau señala, esto no logra nada en un valor de retorno porque el valor de retorno es una copia del puntero en lugar del puntero en sí, y puede asignarse a un puntero no const.

está fuera de lugar El cuarto const, debería ser entre GetName y el cuerpo de la función como esta:

const char* GetName() const { return m.name; } 

Este const especifica que no hay miembros de la clase serán modificados durante la ejecución de GetName.Suponiendo que GetName un miembro de la clase Person, se permitiría este código:

const Person& p; 
p.GetName(); 

Sin esta const, el código anterior sería un fracaso.

+0

+1 para señalar el sinsentido de hacer que el puntero devuelto no se pueda modificar. GCC también lo advierte (el código aún no se compilará si trata las advertencias como errores :)). Es importante saber qué significan estas constras, pero el tipo de devolución de una función parece ser una opción bastante desafortunada para la demostración. – UncleBens

0

dado:

const char const * const GetName() const { return m_name; }; 

La primera y segunda const son equivalentes, pero se permite sólo uno de ellos - es decir, se puede poner const antes o después de que el tipo (char en este caso), pero sólo uno o el otro, no ambos. O bien, sin embargo, dice que los caracteres apuntados por el puntero no se pueden escribir.

El const después de '*' significa que el puntero devuelto por la función no se puede modificar. Esto rara vez se ve en un tipo de devolución; lo que se devuelve es un valor que no se puede modificar en ningún caso (normalmente se asigna a alguna variable). Sin embargo, esto puede ser significativo en otros contextos.

La tercera const solo está permitida en una función de miembro. Se dice que cuando esta función se llama, el puntero this que ha recibido será un T const * const en lugar de un T * const, por lo que la función miembro sólo puede modificar static o mutable miembros del objeto, y si se invoca otras funciones miembro, que debe ser const también. Hay, sin embargo, una advertencia, que también puede descartar la const'ness, en cuyo caso puede modificar lo que considere adecuado (con la advertencia adicional de que si el objeto se definió originalmente como const, en lugar de tener simplemente un const puntero a un objeto normal (no const), los resultados serán indefinidos).

1

Es posible que haya perdido el símbolo "*" antes de la segunda palabra clave const.

const char * const * const GetName() const { return m_name; }; 

Significa que la función devuelve un puntero constante a un puntero constante a un carácter constante.