2011-12-02 10 views
12

Sólo por curiosidad: si he anidado ámbitos, como en este ejemplo de C++ código¿Hay alguna forma de acceder a una variable local en el ámbito externo en C++?

using namespace std; 

int v = 1; // global 

int main (void) 
{ 
    int v = 2; // local 
    { 
     int v = 3; // within subscope 
     cout << "subscope: " << v << endl; 
     // cout << "local: " << v << endl; 
     cout << "global: " << ::v << endl; 
    } 
    cout << "local: " << v << endl; 

    cout << "global: " << ::v << endl; 

} 

¿Hay alguna manera de acceder a la variable v con el valor 2 del ámbito "intermedia" (ni global ni local,)?

+11

Esto no sería válido en C# de todos modos. –

+3

Diría que esta es una práctica bastante mala para empezar, usar el mismo nombre de variable en cada nuevo ámbito no parece ser una buena idea por ningún motivo. –

+0

no. si necesita acceder, cambie el nombre de las variables. – Dani

Respuesta

14

Se puede declarar una nueva referencia como un alias como tal

int main (void) 
{ 
    int v = 2; // local 
    int &vlocal = v; 
    { 
     int v = 3; // within subscope 
     cout << "local: " << vlocal << endl; 
    } 
} 

pero me gustaría evitar esta práctica esto por completo. Pasé horas depurando una construcción así porque se mostró una variable en el depurador como modificada por el alcance y no pude entender cómo se modificó.

+0

y el propósito de esto en lugar de simplemente cambiar el nombre de 'v' a' vlocal' sería? – Nim

+6

@Nim Si al OP le preocupaba cambiar algún código legado de spaghetti con una alteración mínima –

7

La respuesta es No, usted no puede.
Una variable en el ámbito local sombrea la variable en el alcance global y el lenguaje proporciona una forma de acceder a la variable global mediante el uso de nombres calificados del mundo como lo hizo. Pero C++ como un lenguaje no proporciona de todos modos para acceder a la variable de ámbito intermedio.

Teniendo en cuenta que debería permitirse requeriría una gran cantidad de manejo complejo, Imagínese la situación con n cantidad de ámbitos (podría ser infinita) y el manejo de esos.

Le conviene renombrar sus variables intermedias y usar aquellas que serían más lógicas y fáciles de mantener.

+0

¿Cuál es un ejemplo donde el número de ámbitos es infinito? ¿O solo quisiste decir una gran cantidad de telescopios? – Garrett

1

Usted podría fingir como esto:

#include <iostream> 
using namespace std; 
int v = 1; 

int main() 
{ 
     int v = 2; 
     { 
       int &rv = v; // create a reference 
       int v = 3; // then shadow it 

       cout << "subscope: " << v << endl; 
       cout << "local: " << rv << endl; 
       cout << "global: " << ::v << endl; 
     } 
     cout << "local: " << v << endl; 

     cout << "global: " << ::v << endl; 

     return 0; 
} 

Es interesante que esta compila en cygwin g ++ pero segfaults si intenta ejecutarlo:

#include <iostream> 
using namespace std; 
int v = 1; 

int main() 
{ 
     int v = 2; 
     { 
       int &v = v; 
       cout << "subscope: " << v << endl; 
       // cout << "local: " << v << endl; 
       cout << "global: " << ::v << endl; 
     } 
     cout << "local: " << v << endl; 

     cout << "global: " << ::v << endl; 

     return 0; 
} 
4

Hay dos tipos de scope resolution operadores en C++ - alcance unario y un alcance de clase. No hay un alcance de función o "operadores de resolución de ámbito primario particular". Eso hace que sea imposible resolver su problema, ya que, en general, no puede hacer referencia a ámbitos anónimos. Sin embargo, puede crear un alias, cambiar el nombre de las variables o hacer de esto una parte de la clase, lo que implica un cambio de código. Esto es lo más cerca que puedo conseguir sin cambiar el nombre en este caso particular:

#include <iostream> 

using namespace std; 

int v = 1; // global 

class Program 
{ 
    static int v; // local 

public: 
    static int main() 
    { 
     int v = 3; // within subscope 
     cout << "subscope: " << v << endl; 
     cout << "local: " << Program::v << endl; 
     cout << "global: " << ::v << endl; 
    } 
}; 

int Program::v = 2; 

int main() 
{ 
    return Program::main(); 
} 

Hay otras maneras, como asegurarse de que las variables no están optimizados y son en la pila, a continuación, se puede trabajar con la pila directamente a conseguir el valor de la variable que desea, pero no vayamos por ese camino.

Espero que ayude!

Cuestiones relacionadas