2011-05-10 10 views
13

Duplicar posible:
Why isn't the const qualifier working on pointer members on const objects?¿Por qué no hace cumplir C++ const en los datos del puntero?

Considere la siguiente clase que tiene un miembro de puntero int *a. El compilador permite el método const constMod a pesar de que modifica los datos del puntero. ¿Por qué el compilador no establece la información de puntero en el contexto del método const? Si a fuera solo un int, no se nos permitiría modificarlo en un método const.

class ConstTest 
{ 
    public: 

    ConstTest(int *p): a(p) {} 

    void constMod() const { 
     ++(*a); 
    } 

    int *a; 
}; 

Estoy usando g ++ en linux.

+0

la única respuesta es "porque es así", pero creo que la mayoría de nosotros acepta que generalmente es inesperado (al principio), aunque uno puede encontrar razones después. –

+0

C++ de forma predeterminada da una constness llamada bitwise - lo que significa que se asegura de que no se ha cambiado un solo objeto, por lo que solo comprueba la dirección del puntero – rank1

Respuesta

4

Es solo un problema de propiedad ... no hay manera de que el compilador sepa si el objeto apuntado es lógicamente parte del objeto o no, por lo que le queda al programador controlar estos problemas. const miembros pueden realizar operaciones con efectos secundarios, siempre que no modifiquen su propio valor aparente. En realidad no es diferente de dejar que ellos llaman decir std::cout::operator<<() o alguna otra función no constante ....

13

Dentro constMod(), la declaración de a se trata como:

int *const a; 

que significa que el puntero tiene un valor constante, no es lo que puntos a. Parece que espera que se trate como:

const int *a; 

que es diferente.

+1

¿No aclara la pregunta sin responder ...? –

+0

Entonces, ¿por qué es eso? ¿Por qué no hacer cumplir const todo dentro de un método const? Parece extraño tratar los datos del puntero como un efecto secundario. – MattSmith

+0

@Matt: así es C++. Imagine que era un número entero en lugar de un puntero, y no puede cambiar el número entero. Lo que ese entero significa * usted * no tiene nada que ver con su valor. (Podría ser un contador, una antigüedad, etc.) Del mismo modo, el valor de un puntero no tiene nada que ver con lo que señala (simplemente estamos de acuerdo en que el valor de un puntero indica una dirección, todo el tiempo, en lugar de varias cosas como un entero puede, pero la analogía aún se mantiene). Por lo que vale, el lenguaje D actúa como usted espera. – GManNickG

7

El puntero en sí no se modifica, solo los datos apuntan. Incluso si suena extraño desde el punto de vista humano, desde el punto de vista del compilador, ninguno de los miembros de la clase está alterado.

0

¿Cuál es const en el caso anterior es el puntero sí. No está permitido hacer ++a;. Sin embargo, no evita que modifique los datos apuntando a.

0

Creo que aquí intentas cambiar el valor al que apunta el miembro de datos. Si intenta modificar el miembro de datos, sería un error.

Significado, obtendrá error si usted hace un punto a otra cosa en lugar de cambiar el valor de las funciones

0

const miembros no se permitirá modificar a sus miembros.

En su ejemplo, tiene un puntero que señala un int.

Y en el método const, está modificando el valor al que apunta, pero no el puntero en sí.

Pruebe dar, ++a, que realmente modificará el valor del puntero y no se permitirá en su método const.

0

Considere

const T immutable_object0; 
const T immutable_object1; 
const T* mutable_view = ...a condition... ? &immutable_object0 : &immutable_object1; 
// then later you reseat 
mutable_view = ...another condition... ? &immutable_object0 : &immutable_object1; 

o

const int immutable_data[120] 
const int* mutable_view = immutable_data; 
for(const int* end = immutable_data + 120; mutable_view != end; ++mutable_view) { 
    // can't modify *mutable_view 
} 

Se debe a que los punteros no siempre tienen la propiedad. En algunos casos, los punteros son vistas de un objeto (primer ejemplo) o son iteradores en un conjunto sin formato (segundo ejemplo). Para esos casos, no tiene sentido restringir las operaciones disponibles en los punteros solo porque los datos apuntados son inmutables (o vistos como inmutables).

El primer ejemplo es un poco artificial, pero una versión válida es cuando utiliza un miembro de puntero para implementar la asociación de objetos y no desea la molestia de un miembro de referencia. A veces, los tipos apuntados son const.

Cuestiones relacionadas