2011-03-11 19 views
5
#include <iostream> 
using namespace std; 

int main(int argc, char* argv[]) 
{ 
    int i1 = 0; 
    int i2 = 10; 

    const int *p = &i1; 
    int const *p2 = &i1; 
    const int const *p3 = &i1; 

    p = &i2; 
    p2 = &i2; 
    p3 = &i2; 

    cout << *p << endl 
     << *p2 <<endl 
     << *p3 <<endl; 
    return 0; 
} 

El código se puede compilar tanto con VC6.0 como con VC2010. Pero tengo preguntas como golpe:sobre "int const * p" y "const int * p"

const int * p = &i1;

Significa lo que los puntos "p" no se pueden modificar, pero p no puede ser modificado, estoy en lo cierto? por lo

p = &i2;

esta línea será posible respetar, sí?

Esta línea:

int const *p2 = &i1; 

En mi opinión, esto significa p2 no puede ser modificado mientras lo P2 puntos se pueden cambiar, estoy en lo cierto? Por qué los

p2 = &i2;

puede ser compilado?

Sobre esta línea:

const const int * p3 = &i1;

p3 = &i2;

Oh, dios ... que estoy loco. No tengo idea de por qué esta línea se puede compilar sin error ... ¿Puede ayudarme un cuerpo?

Otro código que me confundió está aquí:

class Coo2  
{  
public:  

Coo2() : p(new int(0)) {}  

~Coo2() {delete p;}  


    int const * getP() const 
    {  
     *p = 1;   
     return this->p;  
    }  

private:  
     int* p;  
}; 

por qué este código puede ser compilado? En

const int * getP() const

Tengo cambiar el valor o * p!

+0

'const' se aplica a la cosa de la izquierda, a menos que no haya nada a la izquierda, en cuyo caso se aplica a la cosa de la derecha. (Sí, esto es innecesariamente confuso y tonto.) – GManNickG

+0

'const' al final significa que no se realizarán cambios en el objeto/clase. –

Respuesta

5

Con la ayuda del puntero, en realidad se puede hacer dos cosas.

  1. Puede cambiar los datos a los que apunta, pero no puede apuntar a una ubicación de memoria diferente.
  2. Puede indicar una ubicación de memoria diferente pero no puede cambiar los datos a los que apunta.

Ahora, cuando dices, int const * ptr o int const * ptr, pertenece a la primera categoría. Es igual que - no

const int num = 5; // Both mean the same. 
int const num = 5; 

A, realmente capaz de cambiar a una ubicación diferente, es decir, puntero a una posición constante, sino que será capaz de modificar los datos, la semántica debe ser int* const. Como el contenido del puntero es una constante, debe inicializarse durante la declaración.

int num = 5; 

int* const ptr; // Wrong 
ptr = &num; // Wrong 

int* const ptr = &num; 
*ptr = 100; 

Sin embargo, hay un tercer tipo. Puntero constante a una ubicación constante, que no puede apuntar a una ubicación de memoria diferente ni cambiar los datos a los que apunta. (es decir, const int * const)

Y ahora respondiendo a las preguntas, las dos primeras se pueden compilar porque no apuntan a ubicaciones constantes. Por lo tanto, también se pueden modificar en etapas posteriores.

const int const *p3 = &i1; 
p3 = &i2; // Wrong 

En el fragmento anterior, p3 es un puntero constante a un lugar constante. Entonces, no puede ser modificado.

const al final de una función miembro dice que no va a cambiar el estado del objeto. Cuando dice *p = 1;, no está cambiando el estado del objeto. p aún apunta a la misma ubicación de memoria. Esto no está permitido hacer -

int const * Coo2::getP() const 
{  
    *p = 1; // State of `p` is still not modified. 
    p = new int ; // Error: Changing the memory location to which p points. 
        //  This is what changing the state of object mean and  
        //  is not allowed because of `const` keyword at the end of function 
    return this->p;  
} 

Esperanza, ahora entiendo por qué el programa compila :)

1

No, la palabra clave const antes del * significa que la variable que está señalando es una variable "const" y solo no se puede modificar.

  1. Si quieres un puntero que no se pueden reasignar a continuación, tiene que declarar como Foo* const p = &bar;
  2. Si desea un puntero que apunta a un objeto "const" que no puede ser reasignado declarará como const Foo* const p = &bar

es perfectamente posible tener un puntero de const int* foo pueden asignar a un puntero de const int* const bar al igual que es bueno tener un valor int 's asignado a un const int. Piénsalo de la misma manera.

1

const int * es la misma que const int *

4

int const * p; y const int * p son los mismos. Es cuando el const viene después de la * que la semántica de la expresión cambio.

que sé, es una locura.

+0

'int const * getP() const', ¿el último' const'means no puedo cambiar * p (lo que señala 'p')? –

+0

De acuerdo, su atención al detalle se interpone en su camino hacia el aprendizaje del idioma (eso no es malo). Cuando el const comest después de una firma de funciones, significa que la función miembro (por ejemplo, una que se define que pertenece a un objeto) tiene la intención de no hacer un cambio a un objeto. El compilador hace cumplir esta intención hasta cierto punto. Entonces, si dicha función escribe, o llama a una función que puede escribir en el objeto, en cuestión, o en cualquier otra forma indirecta (pero detectable por el compilador), el compilador arrojará un error. –

+0

@Bug: No, eso significa que la función miembro es 'const'. ¿Tiene un [buen libro introductorio] (http://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list)? – GManNickG

2
const int *p = &i1; 
int const *p2 = &i1; 

Estos dos declarar punteros no constante a los datos const.

Es decir, utilizando p, no se pueden cambiar los datos que apunta. Sin embargo, puede cambiar el puntero, por ejemplo, asignando como p = &i2 que es legal. Pero *p = 87987 es ilegal, ya que los datos se ofrecen a p puntos const!

-

int * const p = &i1; 

Esto declara puntero constante a datos no const. Es decir, p=&i2 es ilegal, pero *p = 98789 es legal.

-

const int * const p = &i1; 

Esto declara puntero constante a los datos const. Es decir, ahora los dos p=&i2 y *p=87897 son ilegales.

2

Los dos son exactamente lo mismo. Lo que importa es la posición de la clasificación en relación con el asterisco (*):

int const *p; // normal pointer to const int 
const int *p; // ditto 

int *const p; // const pointer to normal int (rarely useful) 

int const * const p; // const pointer to const int 
+0

La segunda sección del código: int const * getP() const, ¿el último significa que no puedo cambiar * p (lo que p está señalando)? –

+1

@BugCreater: No, es un calificador en una función de miembro, diciendo que la función no cambia el estado de su objeto, por lo que puede invocarse en un objeto const. –

7

Aquí consideramos 4 tipos de punteros declaraciones:

  1. int * w; Significa que w es un puntero a un valor de tipo entero. Podemos modificar tanto el puntero como su contenido. Si inicializamos w, mientras que la declaración de la siguiente manera: int * w = &a;
    Entonces, ambos por debajo de las operaciones son viables:
    w = &b; (verdadero)
    *w = 1; (verdadero)

  2. int * const x;
    Significa x es un puntero constante que apunta a un valor de tipo entero. Si inicializamos x mientras declaración como a continuación:
    int * const x = &a;
    Entonces, no podemos hacer: x = &b;(wrong) porque x es un puntero constante y no se puede modificar. No se puede hacer: *x = 1;(true), porque el contenido de x no es constante.

  3. int const * y; // ambos significan el mismo
    const int * y;
    Esto significa que Y es un puntero que apunta a un valor entero constante. Si inicializamos y cuando la declaración es la siguiente:
    Entonces, es posible hacer: y=&b;(true) porque y es un puntero no constante que puede apuntar a cualquier parte.
    Sin embargo, no podemos hacer: *y=1;(wrong) porque la variable que y señala es una variable constante y no se puede modificar.

  4. int const * const z; // ambos significan el mismo
    const int * const z;
    significa que z es un puntero constante que apunta a un valor entero constante.Si inicializamos z, mientras que la declaración de la siguiente manera:
    int const * const z = &a;
    Por lo tanto, no de las operaciones siguientes son viables:
    z = &b;(wrong)
    *z = 1;(wrong)

1

Sucintamente; cada combinación de lectura/escritura int & puntero;

int main() { 

    int a,b; 

    int* w;      // read/write int, read/write pointer 
    w= &b;      // good 
    *w= 1;      // good 

    int* const x = &a;   // read only pointer, read/write int 
    // x = &b;     // compilation error 
    *x = 0;      // good 

    int const * y;    // read/write ptr, read only int 
    const int * y2;    // " " " 
    y = &a;      // good 
    // *y = 0;     // compilation error 
    y2 = &a;      // good 
    // *y2 = 0;     // compilation error 

    int const * const z = &a;  // read only ptr and read only int 
    const int * const z2 = &b; // " " " " 
    // *z = 0;     // compilation error 
    // z = &a;     // compilation error 
    // *z2 = 0;     // compilation error 
    // z2 = &a;     // compilation error 

} 
Cuestiones relacionadas