2010-05-10 19 views
16

En C++, quelle est la résolution de portée ("ordre de priorité") pour les noms de variables shadowed? Je n'arrive pas à trouver une réponse concise en ligne.En C++, quelle est la résolution de portée ("ordre de priorité") pour les noms de variables ombrés?

Par exemple:

#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(); 
} 

Je ne peux pas penser à d'autres champs d'application où pourrait entrer en conflit une variable. S'il vous plaît laissez-moi savoir si j'en ai manqué un.

Quel est l'ordre de priorité pour les quatre variables shadow à l'intérieur de la fonction membre bar?

+0

Vous pourriez avoir un bloc de code à l'intérieur de 'bar()' qui déclare également 'shadowed'. –

+0

"scope resolution" –

+0

Ajout d'un cas de bloc de code dans 'bar()'. –

Répondre

31

Vos premières sorties exemple 3. Votre deuxième sorties 4.

La règle générale est que le produit de consultation de la « plus local » au « moins local » variable. Par conséquent, la priorité est ici block -> local -> class -> global.

Vous pouvez également accéder à chaque la plupart des versions de la variable ombré explicitement:

// 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

Il devrait imprimer 3. La règle de base est la plupart du temps pour travailler votre chemin en arrière dans le fichier à la définition la plus récente le compilateur aurait vu (edit: ça n'est pas hors de portée), et c'est ce qu'il utilise. Pour les variables qui sont locales à une classe, vous suivez la même sauf que toutes les variables de classe sont traitées comme si elles étaient définies au début de la définition de classe. Notez que ceci est plus ou moins unique aux classes. Par exemple, le code donné comme:

int i; 

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

Même si est un i qui est locale à la fonction, la définition la plus récente vu où cout est utilisé est mondial, c'est ce que l'i dans cette expression fait référence à. Cependant, si cela était dans une classe:

int i; 

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

    X() : i(2) {} 

    int i; 
}; 

Ensuite, l'expression cout se réfère à X::i même si sa définition n'a pas été encore vu quand y est en cours d'analyse.

+0

+1 Bon point sur les variables non encore déclarées. –

+0

"variables qui sont locales à une classe" Mieux dire: les variables qui sont membres d'une classe. – Melebius