2010-05-10 10 views
16

En C++, ¿cuál es la resolución del alcance ("orden de precedencia") para shadowed nombres de variables? Parece que no puedo encontrar una respuesta concisa en línea.En C++, ¿cuál es la resolución del alcance ("orden de precedencia") para nombres de variables sombreados?

Por ejemplo:

#include <iostream> 

int shadowed = 1; 

struct Foo 
{ 
    Foo() : shadowed(2) {} 

    void bar(int shadowed = 3) 
    { 
     std::cout << shadowed << std::endl; 
      // What does this output? 

     { 
      int shadowed = 4; 
      std::cout << shadowed << std::endl; 
       // What does this output? 
     } 
    } 

    int shadowed; 
}; 


int main() 
{ 
    Foo().bar(); 
} 

No puedo pensar en cualquier otra ámbitos donde una variable podría entrar en conflicto. Por favor, avíseme si me perdí una.

¿Cuál es el orden de prioridad de las cuatro variables shadow cuando está dentro de la función de miembro bar?

+0

Puede tener un bloque de código dentro de 'bar()' que también declara 'shadowed'. –

+0

"resolución de alcance" –

+0

Caso agregado para el bloque de código dentro de 'bar()'. –

Respuesta

31

Sus salidas primer ejemplo 3. Sus segundas salidas 4.

La regla general es que las ganancias de la búsqueda "más locales" a la variable "local menos". Por lo tanto, la precedencia aquí es block -> local -> class -> global.

También puede acceder a cada uno mayoría de las versiones de la variable de sombreado de forma explícita:

// See http://ideone.com/p8Ud5n 
#include <iostream> 

int shadowed = 1; 

struct Foo 
{ 
    int shadowed; 
    Foo() : shadowed(2) {} 
    void bar(int shadowed = 3); 
}; 

void Foo::bar(int shadowed) 
{ 
    std::cout << ::shadowed << std::endl; //Prints 1 
    std::cout << this->shadowed << std::endl; //Prints 2 
    std::cout << shadowed << std::endl; //Prints 3 
    { 
     int shadowed = 4; 
     std::cout << ::shadowed << std::endl; //Prints 1 
     std::cout << this->shadowed << std::endl; //Prints 2 
     //It is not possible to print the argument version of shadowed 
     //here. 
     std::cout << shadowed << std::endl; //Prints 4 
    } 
} 

int main() 
{ 
    Foo().bar(); 
} 
5

Se deberá imprimir 3. La regla básica es sobre todo a su forma de trabajo hacia atrás en el archivo de la definición más reciente el compilador habría visto (editar: eso no ha salido del alcance), y eso es lo que usa. Para las variables que son locales a una clase, siga el mismo excepto que todas las variables de clase se tratan como si estuvieran definidas al principio de la definición de clase. Sin embargo, tenga en cuenta que esto es más o menos exclusivo de las clases. Por ejemplo, el código dado como:

int i; 

int x() { 
    std::cout << i << '\n'; // prints 0; 
    int i=1; 
} 

A pesar de que es un i que es local a la función, la definición más reciente visto donde se utiliza cout es el mundial, así que eso es lo que el i en esa expresión se refiere a. Sin embargo, si esto fuera en una clase:

int i; 

class X { 
    void y() { std::cout << i << "\n"; } 

    X() : i(2) {} 

    int i; 
}; 

Entonces la expresión cout se referiría a X::i a pesar de que su definición no se ha visto aún cuando se está analizando y.

+0

+1 Buen punto acerca de las variables aún no declaradas. –

+0

"variables que son locales a una clase" Mejor decir: variables que son _members_ de una clase. – Melebius

Cuestiones relacionadas